Guidance unification: one canonical home per fact, a measured loader story, and a gate that keeps it true - #7306
Conversation
…e that exists Four mechanical drift classes become build failures: every repo path named by agent guidance (root AGENTS.md/CLAUDE.md, crates/** AGENTS/CLAUDE/ CONTRACT/README, .claude/rules/*.md, .claude/skills/*/SKILL.md) must resolve in the tracked tree; every rules/skills frontmatter paths: glob must match at least one tracked file (the dead-trigger class that let skills.md never fire); every crate directory appears in its family's AGENTS.md crate table (the guidance half of check-target-tree.py); and every crate has a README.md (measured 62/62, so it gates). Extraction is designed against false positives: fenced blocks, placeholder tokens, MCP method names, dated-correction (✎) lines, and 'check-guidance: path-ok' lines are not claims; resolution honors the citation forms measured on the live tree (root-relative, doc-relative, name-prefix, crate-qualified-by-context, module-relative within the citing crate). KNOWN_MISSING is a shrink-only suppression table — a row whose reference stops dangling fails the gate until deleted, and surviving rows print as warnings every run. Fails closed on unreadable files, unparseable frontmatter, broken crate discovery, and near-empty scans (floor constants). Self-test in test-check-guidance.py (23 cases, refusals first, real repository last), wired beside check-target-tree.py in code_style.yml; the test planner classifies all three paths as static-control (verified exit 0). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… specs to CONTRACT.md Steps 2+3 of the guidance unification (docs/reborn/guidance-conventions.md): - Rename the four Module Specs table specs CLAUDE.md -> CONTRACT.md (llm, filesystem, webui, composition), matching the identity/trust precedent. Charter gates repointed (llm module_charter, webui handlers_module_charter) and every live reference updated; pointer stubs left behind so tooling that loads CLAUDE.md still lands on the spec. - Fold the nine substantive out-of-table CLAUDE.md files: wasm, mcp, sandbox, auth, assistant, trace_commons, extension_manager become AGENTS.md-canonical (gates repointed with pinned phrases kept verbatim: the wasm_sandbox_core arch pin, mcp module_charter, auth module_charter, assistant reborn_services_module_charter); network and secrets fold into their README Invariants sections and drop the crate guidance pair entirely. - Mark with the convention's absence-claim annotation the five crate-tier lines grandfathered by check-guidance KNOWN_MISSING (llm CONTRACT.md x3, composition CONTRACT.md, hooks AGENTS.md) and mark trace_commons' prescribed tests/queue.rs mirror as prescriptive-future. - tests/CLAUDE.md: replace the retired root Current-Limitations citation with the measured ironclaw_observability description. End state: zero prose CLAUDE.md outside the Module Specs table at the crate tier (the four ironclaw_agent_loop src/tests directory guides stay, same footing as the tests-tree harness guides). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…adapter Step 1: root AGENTS.md (198 lines) and root CLAUDE.md (286 lines) shared zero identical lines — the forked-pair drift the guidance convention forbids at crate level, live at the root. Root AGENTS.md is now the canonical tool-neutral contract (build/run/debug commands, hard invariants including the unified extension model and the credential_name/extension_name identity rules, the Module Specs table — now uniformly CONTRACT.md and gaining the existing ironclaw_trust/CONTRACT.md row — testing discipline, tree map, discovery, change discipline; 152 lines). Root CLAUDE.md is an @AGENTS.md adapter plus the genuinely Claude-specific tail: skills/rules index, codebase-graph MCP recipes, and the REPL info!/warn! logging rule (51 lines). Cut while merging, each measured against the tree: the v1 Job State Machine (no such state machine exists under crates/), Current Limitations (stale — the observability claim no longer matches the crate), the Skills System section (.claude/rules/skills.md and the domain crate own it), Extracted Crates, the re-derivable key-traits list, and the long channel-onboarding narrative (now three lines pointing at crates/extensions/AGENTS.md and the worked slack example). Every live citation of the root pair's moved sections is repointed (crates/ routing map + README, the deslop-reborn command, types/type-placement rules, skills/common/config crate docs, a loop_host doc comment). The git-ignored .codebase-memory/artifact.json mention carries the absence-claim annotation for the check-guidance KNOWN_MISSING handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The loader question is now measured, not assumed. Headless canary experiment with a discriminating control: a symlinked nested CLAUDE.md's target content IS injected when a file in that directory is read, an @AGENTS.md import inside a nested CLAUDE.md also expands, and a nested AGENTS.md alone is NOT read. So one uniform rule holds everywhere: wherever an AGENTS.md exists, CLAUDE.md sits beside it as a symlink — same bytes, zero maintenance, no second document to drift. 64 pointer stubs become symlinks. The four spec crates keep CONTRACT.md as canonical; their AGENTS.md routes there, so the spec stays one hop away while the working rules now auto-inject instead of costing a voluntary read. Also reconciled check-guidance.py's shrink-only KNOWN_MISSING table: all 8 rows deleted because the content pass fixed the underlying lines, and the three absence-claims the gate then surfaced carry markers. The table is empty. Caveat recorded for the convention: nested injection fires only below cwd, and appears not to fire in subagent sessions — family docs must stand alone when read deliberately. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nd budgets The first version made crate AGENTS.md canonical and CLAUDE.md a pointer, which moved working rules out of Claude Code's auto-inject path. Records what was measured instead: subtree CLAUDE.md injects lazily, symlinks and @imports both carry content, nested AGENTS.md is not read natively, and injection does not fire in subagent sessions — so every doc must stand alone when read deliberately. Adds size budgets per tier, extends scope to .claude/rules and .claude/skills (where the worst drift was), names check-guidance.py as the enforcement with its suppression markers, warns that some guidance is test-parsed (including the heading-shadowing trap), and adds the remove/rename checklist that mirrors add. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The blanket symlink pass broke composition_root_embeds_no_prompt_content, and the gate is right to refuse: its ownership walks do not follow symlinks, so stepping over one would let it report clean on a subtree it never read. This crate keeps a regular pointer file, with the reason written in the file so the next person does not 'fix' the inconsistency back into a break. The uniform alias rule now has two stated exceptions: the root (real file, it carries a Claude-only tail) and composition (real file, this gate). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…marked reference The branch's central invariant — a `CLAUDE.md -> AGENTS.md` symlink beside every AGENTS.md at the root and under crates/ — was unguarded: the audit proved a committed symlink deletion left the gate green (a working-tree deletion only tripped the accidental "cannot read guidance file" refusal). Check 5 now judges the git index (`git ls-files -s` + `cat-file`): the alias must be tracked, mode 120000, targeting exactly `AGENTS.md`. The two real-file exceptions are named rows with reasons (the root adapter's Claude-only tail; composition's symlink-refusing ownership walks), and a row that stops matching the tree fails the gate rather than lingering. Sabotage-verified on the real tree: `git rm --cached` on an alias went red naming the pair; converting one to a tracked regular file went red; restore went green (65 aliases verified). Also from the audit: - A `path-ok` marker now vouches for the one reference immediately preceding it instead of exempting its whole line — the audit slipped a fresh dangling path onto a marked line and passed. The `✎` glyph stays line-scoped by documented design. Both in-tree marker usages already sit marker-after-reference and keep working. - Document the structural blind spot: a dead reference whose first segment died with its whole tree (the v1 `src/…` monolith) reads as historical narration and cannot be flagged; only review catches it. - Re-measure the fail-closed floor comment — the shipped one claimed 174 guidance files / ~800 references / 30 globs against a tree that measures 237 / ~2070 / 38 — and add a floor for alias-site discovery. Self-test grows six cases: index-deleted alias, regular-file alias, wrong-target alias, the load-bearing root exception row, exception rows matching reality, and the marker-narrowing exploit. The `--tracked-files` override marks symlinks as `<path> -> <target>`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…est size budgets Content half of the guidance-unification audit fixes: - architecture-video SKILL.md told readers to read `src/tools/README.md` and `src/workspace/README.md` — the v1 monolith is gone (`git ls-files | grep -c '^src/'` is 0) and the gate structurally cannot flag first-segment-dead paths. Repointed at the Reborn successors: `crates/extensions/AGENTS.md` and `crates/domains/ironclaw_memory/README.md`. - guidance-conventions.md now records what only commit messages knew: the composition real-file exception beside the root one; the four sanctioned ironclaw_agent_loop sub-module CLAUDE.md guides; and the alias rule's actual scope (root + crates/**), naming the two out-of-scope AGENTS.md (docs/reborn/contracts, ironclaw_silk_decoder) instead of a "wherever" wording the tree contradicted. - Size budgets re-derived from measurement (family <=220, crate <=160) with the four crate-tier exceptions named and reasoned. The shipped <=150/<=80 numbers were exceeded by 3 family and 24 of 54 crate docs on day one, which made the budget unreadable as a signal. No document was padded or truncated to fit. - Root CLAUDE.md used the dated-correction glyph on the deliberately untracked `.codebase-memory/artifact.json` reference — suppression duty outside the glyph's documented historical-prose meaning. Swapped for `<!-- check-guidance: path-ok -->` beside the reference. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
🚅 Deployed to the ironclaw-pr-7306 environment in ironclaw-ci-preview
|
🔎 Review · PR #7306
1 actionable findings →The guidance consolidation and contract renames are internally consistent, and the new checker passes its 29 self-tests and the live repository scan. One non-blocking correctness gap remains in the family-table validation. Automatic · PR opened · attempt 1 of 3 · completed in 1m 31s Run details
|
There was a problem hiding this comment.
🔍 Review complete · PR #7306
💬 1 finding
The guidance consolidation and contract renames are internally consistent, and the new checker passes its 29 self-tests and the live repository scan. One non-blocking correctness gap remains in the family-table validation.
Findings
- 🟡 Low · Family-table check accepts incidental mentions in unrelated columns —
scripts/ci/check-guidance.py:814-827
Details are attached to the relevant diff.
Validation and technical details
- Reviewed the complete trusted comparison
refs/ironloop/base...refs/ironloop/headacross all 152 changed paths, including the mechanical symlink conversions, guidance folds, contract renames, Rust reference retargets, workflow integration, checker, and checker self-tests. python3 scripts/ci/test-check-guidance.pypassed all 29 tests.python3 scripts/ci/check-guidance.py --jsonpassed: 237 guidance files, 2,074 references, 38 globs, 62 crates tabled, 65 aliases, and zero reported problems.git diff --check refs/ironloop/base...refs/ironloop/headcompleted cleanly.- Inspected all changed Rust hunks; they retarget documentation/test readers without changing runtime behavior.
- Base:
main - Head:
guidance/unificationatd67af46 - Run:
7d8ca2ea-683f-4abe-a188-1862417a2873
| names = list(dict.fromkeys([crate.basename] + ([crate.package] if crate.package else []))) | ||
| patterns = [_word_pattern(name) for name in names] | ||
| if rows and not any(p.search(row) for row in rows for p in patterns): | ||
| if len(names) == 1: | ||
| spelled = f"`{names[0]}` appears in no table row" | ||
| else: | ||
| joined = " nor ".join(f"`{name}`" for name in names) | ||
| spelled = f"neither {joined} appears in any table row" | ||
| problems.append( | ||
| f" {crate.directory} is a crate of family `{family}`, but " | ||
| f"{spelled} of {family_agents} — the family table no longer " | ||
| "covers its own crates" | ||
| ) | ||
| elif rows: |
There was a problem hiding this comment.
🟡 Low · Family-table check accepts incidental mentions in unrelated columns
The checker considers a crate covered when its directory or package name appears anywhere in any Markdown table row. If a crate's actual row is removed but another crate's charter or routing text mentions it, the check still increments tabled and CI passes. This undermines the new gate's claim that every crate appears in its family table. Parse the crate-identity column (ideally its link target) and compare that field exactly; add a regression test where the missing crate is mentioned only in another row's description.
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe repository guidance model now uses ChangesGuidance and contract migration
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 17
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/code_style.yml:
- Around line 199-205: Extend the has_code change-detection pattern used by
fast-checks to include all guidance surfaces governed by check-guidance.py:
.claude/rules/, .claude/skills/, docs/, and the root AGENTS.md and CLAUDE.md
files. Keep the existing crates/, tests/, scripts/ci/, and workflow matches
unchanged so edits to any guidance input run the “Check guidance references the
tracked tree” step.
In `@AGENTS.md`:
- Around line 11-15: Update the documented cargo clippy command to pass -- -D
warnings so Clippy warnings cause validation to fail, preserving the stated
zero-warning requirement.
- Line 70: Update the error-propagation example in AGENTS.md to preserve the
original error source instead of converting it solely with e.to_string(). Show a
thiserror error variant with a #[source] field, or use the repository’s
established cause-preserving constructor, while adding context through ?. Keep
the guidance against unwrap() and expect() unchanged.
In `@crates/app/ironclaw_composition/CONTRACT.md`:
- Around line 427-435: Align the `webui_v2_app` API contract and usage with its
implementation: inspect the function definition and all call sites, then update
the CONTRACT.md table and example so the declared return type and error
propagation behavior match. Specifically, remove the example’s `?` if the
function returns `Router`, or update both documentation entries if the
implementation returns a `Result`, while preserving the surrounding setup flow.
- Around line 373-375: Update the “Connection limit (SSE)” statement in
CONTRACT.md to accurately document the WebSocket bound for stream_events_ws.
Verify the implementation and AGENTS.md confirm whether WebSockets share
SseCapacity; if so, state that both SSE and WebSocket streams are limited to 3
per (tenant, user) with a 5-minute maximum lifetime. If they do not share it,
add and test an explicit bounded WebSocket policy before documenting it as a
security invariant.
In `@crates/app/ironclaw_config/AGENTS.md`:
- Line 5: Resolve the documentation alias inconsistency for
crates/app/ironclaw_config by choosing either to retain CLAUDE.md as an
intentional AGENTS.md alias or remove the alias. Apply that same choice
consistently in the module specs table and guidance checker in the root
AGENTS.md, and update the module’s absence statement accordingly.
In `@crates/contracts/ironclaw_host_api/src/resource.rs`:
- Line 72: Update the security comment in resource.rs to reference the canonical
guidance path crates/product/ironclaw_assistant/AGENTS.md instead of
crates/ironclaw_assistant/AGENTS.md, leaving the surrounding comment unchanged.
In `@crates/domains/ironclaw_llm/CONTRACT.md`:
- Line 188: Inspect apply_decorator_chain and reconcile the documented provider
composition so FailoverProvider and CircuitBreakerProvider use the same nesting
everywhere. Update the prose, diagram, and constructor assembly order in
CONTRACT.md to match the implementation’s actual behavior, preserving the
authoritative module contract and ensuring circuit-open handling and fallback
behavior are described consistently.
In `@crates/extensions/ironclaw_extension_manager/AGENTS.md`:
- Around line 11-17: Update the transition statement in the AGENTS.md
documentation so ironclaw_extension_host consistently reflects its current
extensions/loops layer, removing the outdated scheduled move from products to
loops while preserving the one-way dependency constraint.
In `@crates/product/ironclaw_assistant/AGENTS.md`:
- Around line 347-351: Update the Validation section to document both
default-feature and --all-features Clippy checks for the ironclaw_assistant
crate, including its test-support feature. Replace the filtered
reborn_crate_dependency_boundaries_hold architecture command with the full
ironclaw_architecture_tests package check for dependency/API or test-pinned
guidance changes.
In `@crates/product/ironclaw_webui/CONTRACT.md`:
- Around line 480-482: Update the validation commands in CONTRACT.md to document
both required Clippy lanes: run the default-feature lane first with
--all-targets and -D warnings, then run the existing all-features lane with
--all-targets and -D warnings; ensure the test command coverage is retained as
documented.
In `@crates/product/ironclaw_webui/src/webui_serve.rs`:
- Line 192: Update the AGENTS.md reference in the nearby documentation comment
to use the canonical path crates/product/ironclaw_assistant/AGENTS.md instead of
crates/ironclaw_assistant/AGENTS.md, preserving the trusted host configuration
guidance.
In `@crates/substrates/ironclaw_filesystem/CONTRACT.md`:
- Around line 85-86: Verify the actual dependencies in the ironclaw_filesystem
Cargo.toml, then reconcile CONTRACT.md’s runtime dependency rule with that
dependency graph and the README inventory. If ironclaw_libsql_runtime is
required, allow and document it consistently; otherwise remove the stale
inventory entry, keeping CONTRACT.md as the canonical specification.
In `@scripts/ci/check-guidance.py`:
- Around line 728-750: Update glob_to_regex to translate brace alternation such
as {rs,toml} into a regex alternation group instead of escaping the braces. Add
a parsing branch that splits brace contents into alternatives, recursively
converts each alternative as needed, and preserves existing wildcard behavior
for patterns like crates/**/*.{rs,toml}.
- Around line 188-191: Raise the MIN_RULE_GLOBS and MIN_ALIAS_PAIRS thresholds
in the guidance validation constants to values near the measured shipped-tree
counts, with reasonable headroom, matching the approach used by
MIN_GUIDANCE_FILES and MIN_PATH_REFERENCES.
In `@scripts/ci/test-check-guidance.py`:
- Around line 519-527: Document the external-repository dependency in
test_real_repository_guidance_is_clean: add a docstring stating that GATE.main
uses git and requires a checkout with the tracked tree, and that failures in
shallow or exported trees are environmental rather than guidance drift. Leave
the test behavior unchanged.
- Around line 330-346: Add coverage for brace alternation to
test_glob_translation_handles_the_repo_shapes using representative matching and
non-matching paths, and add a separate test_duplicate_known_missing_rows_fail
that builds the fixture, passes the same GATE.Suppression row twice to run_gate
via known_missing, and asserts exit code 1 with the “one debt, one row” message.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 363387f7-2c25-4271-9e78-31ed9869a3ba
📒 Files selected for processing (192)
.claude/commands/deslop-reborn.md.claude/rules/database.md.claude/rules/type-placement.md.claude/rules/types.md.claude/skills/architecture-video/SKILL.md.github/workflows/code_style.ymlAGENTS.mdCLAUDE.mdCONTRIBUTING.mdcrates/AGENTS.mdcrates/CLAUDE.mdcrates/README.mdcrates/app/AGENTS.mdcrates/app/CLAUDE.mdcrates/app/ironclaw_architecture_tests/CLAUDE.mdcrates/app/ironclaw_architecture_tests/CLAUDE.mdcrates/app/ironclaw_architecture_tests/tests/reborn_composition_boundaries.rscrates/app/ironclaw_architecture_tests/tests/reborn_dependency_boundaries.rscrates/app/ironclaw_cli/CLAUDE.mdcrates/app/ironclaw_composition/AGENTS.mdcrates/app/ironclaw_composition/CLAUDE.mdcrates/app/ironclaw_composition/CONTRACT.mdcrates/app/ironclaw_composition/README.mdcrates/app/ironclaw_composition/src/lib.rscrates/app/ironclaw_composition/src/observability/hooks/factory.rscrates/app/ironclaw_composition/src/observability/trajectory_observer.rscrates/app/ironclaw_composition/src/root/product_live_adapters.rscrates/app/ironclaw_config/AGENTS.mdcrates/app/ironclaw_config/CLAUDE.mdcrates/contracts/CLAUDE.mdcrates/contracts/ironclaw_common/AGENTS.mdcrates/contracts/ironclaw_common/CLAUDE.mdcrates/contracts/ironclaw_extension_contracts/CLAUDE.mdcrates/contracts/ironclaw_extension_contracts/CLAUDE.mdcrates/contracts/ironclaw_host_api/CLAUDE.mdcrates/contracts/ironclaw_host_api/CLAUDE.mdcrates/contracts/ironclaw_host_api/src/resource.rscrates/contracts/ironclaw_loop_contracts/CLAUDE.mdcrates/contracts/ironclaw_loop_contracts/CLAUDE.mdcrates/contracts/ironclaw_product_contracts/CLAUDE.mdcrates/contracts/ironclaw_product_contracts/CLAUDE.mdcrates/domains/AGENTS.mdcrates/domains/CLAUDE.mdcrates/domains/ironclaw_auth/AGENTS.mdcrates/domains/ironclaw_auth/CLAUDE.mdcrates/domains/ironclaw_auth/CLAUDE.mdcrates/domains/ironclaw_auth/README.mdcrates/domains/ironclaw_auth/src/engine/mod.rscrates/domains/ironclaw_auth/src/product_auth/mod.rscrates/domains/ironclaw_auth/tests/module_charter.rscrates/domains/ironclaw_conversations/CLAUDE.mdcrates/domains/ironclaw_conversations/CLAUDE.mdcrates/domains/ironclaw_extractors/CLAUDE.mdcrates/domains/ironclaw_identity/CONTRACT.mdcrates/domains/ironclaw_identity/src/identity_store/directory.rscrates/domains/ironclaw_llm/AGENTS.mdcrates/domains/ironclaw_llm/CLAUDE.mdcrates/domains/ironclaw_llm/CLAUDE.mdcrates/domains/ironclaw_llm/CONTRACT.mdcrates/domains/ironclaw_llm/README.mdcrates/domains/ironclaw_llm/src/error.rscrates/domains/ironclaw_llm/tests/module_charter.rscrates/domains/ironclaw_memory/CLAUDE.mdcrates/domains/ironclaw_memory/CLAUDE.mdcrates/domains/ironclaw_outbound/CLAUDE.mdcrates/domains/ironclaw_outbound/CLAUDE.mdcrates/domains/ironclaw_skills/AGENTS.mdcrates/domains/ironclaw_skills/CLAUDE.mdcrates/domains/ironclaw_skills/README.mdcrates/domains/ironclaw_threads/CLAUDE.mdcrates/domains/ironclaw_threads/CLAUDE.mdcrates/domains/ironclaw_trace_commons/AGENTS.mdcrates/domains/ironclaw_trace_commons/CLAUDE.mdcrates/domains/ironclaw_trace_commons/CLAUDE.mdcrates/domains/ironclaw_trace_commons/README.mdcrates/domains/ironclaw_triggers/CLAUDE.mdcrates/events/CLAUDE.mdcrates/events/ironclaw_event_log/CLAUDE.mdcrates/events/ironclaw_event_log/CLAUDE.mdcrates/events/ironclaw_event_projections/CLAUDE.mdcrates/events/ironclaw_event_projections/CLAUDE.mdcrates/events/ironclaw_event_store/CLAUDE.mdcrates/events/ironclaw_event_streams/CLAUDE.mdcrates/events/ironclaw_event_streams/CLAUDE.mdcrates/extensions/CLAUDE.mdcrates/extensions/ironclaw_extension_host/README.mdcrates/extensions/ironclaw_extension_manager/AGENTS.mdcrates/extensions/ironclaw_extension_manager/CLAUDE.mdcrates/extensions/ironclaw_extension_manager/CLAUDE.mdcrates/extensions/ironclaw_extension_manager/README.mdcrates/extensions/ironclaw_extension_registry/CLAUDE.mdcrates/extensions/ironclaw_extension_registry/CLAUDE.mdcrates/extensions/ironclaw_extension_support/CLAUDE.mdcrates/extensions/packages/memory-native/CLAUDE.mdcrates/extensions/packages/memory-native/CLAUDE.mdcrates/extensions/packages/memory-native/src/repo/filesystem.rscrates/extensions/packages/slack/CLAUDE.mdcrates/extensions/packages/telegram/CLAUDE.mdcrates/kernel/CLAUDE.mdcrates/kernel/ironclaw_approvals/CLAUDE.mdcrates/kernel/ironclaw_approvals/CLAUDE.mdcrates/kernel/ironclaw_authorization/CLAUDE.mdcrates/kernel/ironclaw_authorization/CLAUDE.mdcrates/kernel/ironclaw_capabilities/CLAUDE.mdcrates/kernel/ironclaw_capabilities/CLAUDE.mdcrates/kernel/ironclaw_capabilities/tests/capability_host_auth_resume_contract.rscrates/kernel/ironclaw_capabilities/tests/capability_host_invocation_state_contract.rscrates/kernel/ironclaw_host_runtime/CLAUDE.mdcrates/kernel/ironclaw_host_runtime/CLAUDE.mdcrates/kernel/ironclaw_processes/CLAUDE.mdcrates/kernel/ironclaw_processes/CLAUDE.mdcrates/kernel/ironclaw_resources/CLAUDE.mdcrates/kernel/ironclaw_resources/CLAUDE.mdcrates/kernel/ironclaw_runtime_policy/CLAUDE.mdcrates/kernel/ironclaw_runtime_policy/CLAUDE.mdcrates/kernel/ironclaw_trust/CLAUDE.mdcrates/kernel/ironclaw_trust/CLAUDE.mdcrates/kernel/ironclaw_turns/CLAUDE.mdcrates/kernel/ironclaw_turns/CLAUDE.mdcrates/lanes/AGENTS.mdcrates/lanes/CLAUDE.mdcrates/lanes/ironclaw_mcp/AGENTS.mdcrates/lanes/ironclaw_mcp/CLAUDE.mdcrates/lanes/ironclaw_mcp/CLAUDE.mdcrates/lanes/ironclaw_mcp/README.mdcrates/lanes/ironclaw_mcp/tests/module_charter.rscrates/lanes/ironclaw_sandbox/AGENTS.mdcrates/lanes/ironclaw_sandbox/CLAUDE.mdcrates/lanes/ironclaw_sandbox/CLAUDE.mdcrates/lanes/ironclaw_sandbox/README.mdcrates/lanes/ironclaw_sandbox/src/lib.rscrates/lanes/ironclaw_wasm/AGENTS.mdcrates/lanes/ironclaw_wasm/CLAUDE.mdcrates/lanes/ironclaw_wasm/CLAUDE.mdcrates/lanes/ironclaw_wasm/README.mdcrates/loop/CLAUDE.mdcrates/loop/ironclaw_agent_loop/CLAUDE.mdcrates/loop/ironclaw_agent_loop/CLAUDE.mdcrates/loop/ironclaw_hooks/AGENTS.mdcrates/loop/ironclaw_hooks/CLAUDE.mdcrates/loop/ironclaw_hooks/CLAUDE.mdcrates/loop/ironclaw_loop_host/CLAUDE.mdcrates/loop/ironclaw_loop_host/CLAUDE.mdcrates/loop/ironclaw_loop_host/src/thread_resolving_model_gateway.rscrates/loop/ironclaw_turn_runner/AGENTS.mdcrates/loop/ironclaw_turn_runner/CLAUDE.mdcrates/loop/ironclaw_turn_runner/CLAUDE.mdcrates/product/AGENTS.mdcrates/product/CLAUDE.mdcrates/product/ironclaw_assistant/AGENTS.mdcrates/product/ironclaw_assistant/CLAUDE.mdcrates/product/ironclaw_assistant/CLAUDE.mdcrates/product/ironclaw_assistant/README.mdcrates/product/ironclaw_assistant/src/reborn_services.rscrates/product/ironclaw_assistant/tests/reborn_services_module_charter.rscrates/product/ironclaw_host_ingress/CLAUDE.mdcrates/product/ironclaw_host_ingress/CLAUDE.mdcrates/product/ironclaw_openai_compat/CLAUDE.mdcrates/product/ironclaw_openai_compat/CLAUDE.mdcrates/product/ironclaw_operator/CLAUDE.mdcrates/product/ironclaw_operator/CLAUDE.mdcrates/product/ironclaw_webui/AGENTS.mdcrates/product/ironclaw_webui/CLAUDE.mdcrates/product/ironclaw_webui/CLAUDE.mdcrates/product/ironclaw_webui/CONTRACT.mdcrates/product/ironclaw_webui/README.mdcrates/product/ironclaw_webui/src/auth/github.rscrates/product/ironclaw_webui/src/auth/pending.rscrates/product/ironclaw_webui/src/webui_body_limit.rscrates/product/ironclaw_webui/src/webui_rate_limit.rscrates/product/ironclaw_webui/src/webui_serve.rscrates/product/ironclaw_webui/tests/github_oauth_routes.rscrates/product/ironclaw_webui/tests/handlers_module_charter.rscrates/substrates/CLAUDE.mdcrates/substrates/ironclaw_filesystem/AGENTS.mdcrates/substrates/ironclaw_filesystem/CLAUDE.mdcrates/substrates/ironclaw_filesystem/CLAUDE.mdcrates/substrates/ironclaw_filesystem/CONTRACT.mdcrates/substrates/ironclaw_filesystem/README.mdcrates/substrates/ironclaw_network/AGENTS.mdcrates/substrates/ironclaw_network/CLAUDE.mdcrates/substrates/ironclaw_network/README.mdcrates/substrates/ironclaw_observability/CLAUDE.mdcrates/substrates/ironclaw_safety/CLAUDE.mdcrates/substrates/ironclaw_secrets/AGENTS.mdcrates/substrates/ironclaw_secrets/CLAUDE.mdcrates/substrates/ironclaw_secrets/README.mdcrates/substrates/ironclaw_secrets/src/secret_store.rsdocs/reborn/guidance-conventions.mdscripts/ci/check-guidance.pyscripts/ci/test-check-guidance.pytests/CLAUDE.md
💤 Files with no reviewable changes (5)
- crates/domains/ironclaw_skills/AGENTS.md
- crates/substrates/ironclaw_secrets/AGENTS.md
- crates/substrates/ironclaw_network/CLAUDE.md
- crates/substrates/ironclaw_network/AGENTS.md
- crates/substrates/ironclaw_secrets/CLAUDE.md
| MIN_GUIDANCE_FILES = 40 | ||
| MIN_PATH_REFERENCES = 80 | ||
| MIN_RULE_GLOBS = 1 | ||
| MIN_ALIAS_PAIRS = 10 |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Raise MIN_RULE_GLOBS and MIN_ALIAS_PAIRS toward the measured values.
The comment records 38 rule globs and 65 alias pairs on the shipped tree, but the floors are 1 and 10. A frontmatter parser that silently degrades to one glob still passes, which is the exact failure mode the floors exist to catch. Set them near the measured counts with headroom, as done for the other two floors.
♻️ Proposed floors
-MIN_RULE_GLOBS = 1
-MIN_ALIAS_PAIRS = 10
+MIN_RULE_GLOBS = 20
+MIN_ALIAS_PAIRS = 40📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| MIN_GUIDANCE_FILES = 40 | |
| MIN_PATH_REFERENCES = 80 | |
| MIN_RULE_GLOBS = 1 | |
| MIN_ALIAS_PAIRS = 10 | |
| MIN_GUIDANCE_FILES = 40 | |
| MIN_PATH_REFERENCES = 80 | |
| MIN_RULE_GLOBS = 20 | |
| MIN_ALIAS_PAIRS = 40 |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/ci/check-guidance.py` around lines 188 - 191, Raise the
MIN_RULE_GLOBS and MIN_ALIAS_PAIRS thresholds in the guidance validation
constants to values near the measured shipped-tree counts, with reasonable
headroom, matching the approach used by MIN_GUIDANCE_FILES and
MIN_PATH_REFERENCES.
… governs, brace globs, honest floors, identity-column family tables, doc-truth fixes
Trigger (Major, the inert-guard finding): fast-checks was gated on has_code,
whose regex covers none of .claude/, the root AGENTS.md/CLAUDE.md pair, or
docs/ — so a PR editing only a rule's paths: trigger skipped the gate built
for exactly that change. New has_guidance output OR-s those surfaces into
fast-checks only (clippy/JS lanes stay code-scoped); has_code keeps its
pinned meaning. Pinned by a ws12_workflow_contracts.py row and verified by
replaying representative change lists through the workflow's own extracted
EREs.
check-guidance.py: glob_to_regex now translates {a,b} brace alternation
(nested; unmatched braces stay literal) so a legitimate crates/**/*.{rs,toml}
trigger counts as live instead of being reported dead; MIN_RULE_GLOBS 1->20
and MIN_ALIAS_PAIRS 10->40 (~half of measured 38/65, so a degraded parser
refuses instead of passing); family-table coverage now requires the crate in
a row's identity (first) column — an incidental mention in another row's
prose no longer counts (measured 0 regressions on the live tree). Self-tests:
+3 (brace trigger end-to-end, duplicate KNOWN_MISSING rows, identity-column
regression) and the real-repository case documents its deliberate git
coupling. Floors sabotage-verified.
Doc truth, measured against code: composition CONTRACT — WS stream shares
SseCapacity (stream_events_ws try_acquire, pinned test) replacing 'No WS
surface to bound', webui_v2_app returns Result<Router, WebuiServeError>;
llm CONTRACT — the circuit breaker wraps failover (apply_decorator_chain
order), not the reverse; filesystem CONTRACT — dependency rule now names the
real manifest set (+libsql_runtime, +observability); extension_manager
AGENTS — the loops layer flip landed (layer = "loops"); four stale 'has no
CLAUDE.md' claims updated for the new symlink aliases (config, common,
event_store x2); root AGENTS — clippy line gains -- -D warnings (CI denies
warnings; unflagged clippy exits 0 with them) and the error bullet routes to
.claude/rules/error-handling.md; assistant/webui validation sections document
the real lane structure (self-dev-dep unifies test-support on, so the missing
shape is the no-dev-deps production lane, the #7119 class).
Stale pre-family paths in .rs prose: 594 crates/ironclaw_* citations
measured; 130 sit in comments, of which 106 repointed to their family homes
(every rewritten path verified to resolve), 10 of those needed deeper
repoints (files that moved crates: capability_host.rs, channel_pairing.rs,
approval_store_contract.rs, secret_store.rs, loop_contracts
instruction_bundle.rs, assistant communication_context.rs, loop_host
surface_disclosure.rs, resolver_tests.rs), 24 left deliberately (flat-
spelling narration about the family move itself, deleted-crate history,
synthetic fixture names, and two #6945-class pointers whose target is gone
at every spelling). 464 string-literal citations left: the specificity
test resolves legacy spellings through the crate inventory by design.
Triage of PR #7306 review comments; no gate weakened, both alias
exceptions preserved.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…_policy_org_ceiling_yolo.rs reborn_pr_test_plan.py has no mapping for this root test (it matches neither the tests/reborn_* partition inventory nor any other arm), so ANY PR touching it fails 'Detect Reborn test scope' — a pre-existing planner gap, confirmed against origin/main with a one-file changed list. The stale crates/ironclaw_runtime_policy comment path inside it stays until the planner learns the file; noted for follow-up rather than smuggling planner surgery into a review-triage branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s 'zero warnings' Same class as the root AGENTS.md fix: unflagged clippy exits 0 with warnings, so the annotation overclaimed. CONTRIBUTING's two-tier design (loose iteration block, then a stricter pre-PR block that already carries -- -D warnings) is deliberate and stays; only the claim is aligned. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CodeRabbit triage: 17 fixed, 1 refutedPushed The one that mattered: the gate didn't run for the files it governs
The two reported stale paths were 105CodeRabbit found two Refuted, with evidence
Two fixed with the reasoning correctedThe clippy-lane comments asked for Pre-existing drift fixed while here, code as arbiter each timeWS capacity ( Recorded, not fixedA pre-existing planner gap: @coderabbitai full review 🤖 Generated with Claude Code |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/code_style.yml:
- Around line 138-141: Update the code-style job’s no-code branch to inspect
needs.fast-checks.result when needs.changes.outputs.has_guidance is true, and
fail the job if that result is unsuccessful. Preserve the existing has_code
behavior and ensure guidance-only runs cannot exit before propagating
fast-checks failures to the required roll-up.
In `@crates/loop/ironclaw_hooks/src/dispatch/mod.rs`:
- Line 3476: Update the loader-responsibility documentation reference near the
existing CLAUDE.md mention to point to the canonical
crates/loop/ironclaw_hooks/AGENTS.md path, removing the alias reference while
preserving the surrounding documentation.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8ea8e65d-6b73-42be-b0e0-82ce54b20a64
📒 Files selected for processing (99)
.github/workflows/code_style.ymlAGENTS.mdCONTRIBUTING.mdcrates/app/ironclaw_architecture_tests/tests/reborn_authorized_seal_ratchet.rscrates/app/ironclaw_architecture_tests/tests/reborn_dependency_boundaries.rscrates/app/ironclaw_architecture_tests/tests/reborn_deployment_mode_branching_ratchet.rscrates/app/ironclaw_architecture_tests/tests/reborn_extension_host_port_inversion.rscrates/app/ironclaw_architecture_tests/tests/reborn_extension_manager_split.rscrates/app/ironclaw_architecture_tests/tests/reborn_extension_specificity.rscrates/app/ironclaw_architecture_tests/tests/reborn_persistence_driver_boundary.rscrates/app/ironclaw_architecture_tests/tests/reborn_product_contract_location_scan.rscrates/app/ironclaw_architecture_tests/tests/reborn_registration_pipeline_boundary.rscrates/app/ironclaw_architecture_tests/tests/reborn_restructure_baselines.rscrates/app/ironclaw_architecture_tests/tests/reborn_same_layer_edge_inventory.rscrates/app/ironclaw_cli/src/commands/config/init.rscrates/app/ironclaw_cli/src/commands/onboard/master_key.rscrates/app/ironclaw_composition/CONTRACT.mdcrates/app/ironclaw_composition/src/google_oauth_secret_store.rscrates/app/ironclaw_composition/src/runtime.rscrates/app/ironclaw_composition/tests/provider_admin_probe.rscrates/app/ironclaw_config/AGENTS.mdcrates/app/ironclaw_config/src/config_file.rscrates/contracts/ironclaw_common/AGENTS.mdcrates/contracts/ironclaw_extension_contracts/src/lib.rscrates/contracts/ironclaw_extension_contracts/src/verified_inbound.rscrates/contracts/ironclaw_host_api/src/action.rscrates/contracts/ironclaw_host_api/src/resource.rscrates/contracts/ironclaw_host_api/src/trust.rscrates/contracts/ironclaw_product_contracts/src/lib.rscrates/contracts/ironclaw_product_contracts/src/operator_secrets.rscrates/domains/ironclaw_llm/CONTRACT.mdcrates/events/ironclaw_event_store/AGENTS.mdcrates/events/ironclaw_event_store/README.mdcrates/extensions/ironclaw_extension_host/src/channel_host/e2e_tests.rscrates/extensions/ironclaw_extension_host/src/channel_identity_store.rscrates/extensions/ironclaw_extension_host/src/test_support/first_party_registrars.rscrates/extensions/ironclaw_extension_host/tests/lifecycle_restore_contract.rscrates/extensions/ironclaw_extension_manager/AGENTS.mdcrates/extensions/ironclaw_extension_registry/tests/product_adapter_manifest_ingestion.rscrates/kernel/ironclaw_host_runtime/tests/reborn_durable_restart_integration.rscrates/kernel/ironclaw_resources/tests/resource_governor_contract.rscrates/kernel/ironclaw_trust/src/lib.rscrates/lanes/ironclaw_sandbox/src/sandbox_process/network_allowlist.rscrates/loop/ironclaw_hooks/src/dispatch/mod.rscrates/loop/ironclaw_hooks/src/manifest.rscrates/loop/ironclaw_loop_host/src/await_edge_port.rscrates/product/ironclaw_assistant/AGENTS.mdcrates/product/ironclaw_assistant/src/automation_product_service/tests.rscrates/product/ironclaw_operator/src/llm_admin/llm_config_service.rscrates/product/ironclaw_operator/src/llm_admin/llm_key_store.rscrates/product/ironclaw_webui/CONTRACT.mdcrates/product/ironclaw_webui/src/webui_rate_limit_router_contract_test.rscrates/product/ironclaw_webui/src/webui_serve.rscrates/product/ironclaw_webui/src/webui_v2/static_assets/mod.rscrates/product/ironclaw_webui/tests/serve_loop.rscrates/substrates/ironclaw_filesystem/CONTRACT.mdcrates/substrates/ironclaw_network/src/policy.rscrates/substrates/ironclaw_network/tests/network_policy_contract.rscrates/substrates/ironclaw_observability/src/lib.rscrates/substrates/ironclaw_safety/src/leak_detector.rsscripts/ci/check-guidance.pyscripts/ci/test-check-guidance.pyscripts/ci/ws12_workflow_contracts.pytests/integration/attach.rstests/integration/auth/oauth_connect.rstests/integration/extension_user_lifecycle_isolation.rstests/integration/golden_payload.rstests/integration/group_approvals/scenario_failure_category_demasked.rstests/integration/group_triggers/scenario_delivery_target_fail_closed.rstests/integration/group_triggers/scenario_triggered_gate.rstests/integration/hooks.rstests/integration/hosted_mcp_registration.rstests/integration/mcp.rstests/integration/safety.rstests/integration/support/assertions.rstests/integration/support/builder.rstests/integration/support/comm_context.rstests/integration/support/doubles/host_runtime_harness_capability_port_factory.rstests/integration/support/doubles/recording_approval_request_store.rstests/integration/support/doubles/recording_capability_result_writer.rstests/integration/support/doubles/recording_delegating_capability_port.rstests/integration/support/doubles/recording_host_runtime.rstests/integration/support/doubles/recording_network_http_egress.rstests/integration/support/doubles/recording_network_http_transport.rstests/integration/support/doubles/recording_runtime_http_egress.rstests/integration/support/group_options.rstests/integration/support/harness/mod.rstests/integration/support/harness/profiles/extension.rstests/integration/support/planned_runtime_parts_shape.rstests/integration/surface_disclosure.rstests/integration/tool_call.rstests/integration/tool_disclosure.rstests/integration/trace_capture.rstests/integration/webui_v2_product_api.rstests/integration/webui_v2_router_smoke.rstests/integration/wiring_parity.rstests/reborn_qa_channel_delivery.rstests/reborn_qa_connect_flows.rstests/reborn_qa_routines.rs
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== PR metadata and changed files ==='
gh pr view 7306 --repo nearai/ironclaw --json headRefOid,baseRefOid,files \
--jq '.headRefOid, .baseRefOid, (.files[] | "\(.path)\t+\(.additions)/-\(.deletions)")'
echo '=== Relevant file outlines ==='
ast-grep outline .github/workflows/code_style.yml --items all 2>/dev/null || true
ast-grep outline scripts/ci/check-guidance.py --items all --type class,function 2>/dev/null || true
ast-grep outline scripts/ci/test-check-guidance.py --items all --type class,function 2>/dev/null || true
ast-grep outline scripts/ci/ws12_workflow_contracts.py --items all --type class,function 2>/dev/null || true
echo '=== Workflow scope and gate conditions ==='
rg -n -C 8 'has_code|has_guidance|fast-checks|paths-filter|check-guidance' \
.github/workflows/code_style.yml scripts/ci/ws12_workflow_contracts.py
echo '=== Guidance checker entry points and key invariants ==='
rg -n -C 5 'def (load_tracked|discover_guidance|extract_references|check_references|parse_frontmatter_paths|glob_to_regex|check_rule_globs|check_family_tables|check_claude_aliases|main)|MIN_|EXCEPTION|SUPPRESSION|CLAUDE|AGENTS|CONTRACT' \
scripts/ci/check-guidance.py scripts/ci/test-check-guidance.py
echo '=== PR diff for high-risk files ==='
gh pr diff 7306 --repo nearai/ironclaw -- \
.github/workflows/code_style.yml \
scripts/ci/check-guidance.py \
scripts/ci/test-check-guidance.py \
scripts/ci/ws12_workflow_contracts.py \
docs/reborn/guidance-conventions.md \
AGENTS.md CLAUDE.mdLength of output: 86231 🏁 Script executed: #!/bin/bash
set -euo pipefail
base='9c85269c86a113c8e9645de57fb9a89d8826f3f0'
head='b149bfbf227b87fbe1aceb5c6d28c42e95dd89de'
echo '=== Required roll-up branch ==='
sed -n '514,610p' .github/workflows/code_style.yml
echo '=== Workflow contract filter and result assertions ==='
sed -n '330,430p' scripts/ci/ws12_workflow_contracts.py
sed -n '560,660p' scripts/ci/ws12_workflow_contracts.py
rg -n -C 5 'code-style|fast-checks|has_guidance|job_result_ok|No code changes' \
scripts/ci/test_ws12_workflow_contracts.py scripts/ci/ws12_workflow_contracts.py
echo '=== Base-to-head workflow diff ==='
git diff --no-ext-diff --unified=50 "$base" "$head" -- .github/workflows/code_style.yml
echo '=== Guidance-only CI result semantics in the existing test suite ==='
rg -n -C 4 'has_guidance|fast-checks.*failure|fast-checks.*skipped|has_code.*false|No code changes' \
scripts/ci --glob '*.py' --glob '*.sh'Length of output: 31477
You are interacting with an AI system. |
There was a problem hiding this comment.
Actionable comments posted: 6
♻️ Duplicate comments (1)
.github/workflows/code_style.yml (1)
138-141:⚠️ Potential issue | 🟠 MajorPropagate guidance-only failures to the required roll-up.
When
has_guidanceis true andhas_codeis false, Line 141 runsfast-checks. Thecode-styleno-code branch at Line 531 through Line 537 exits without checkingneeds.fast-checks.result. A failing guidance check can still produce a green requiredCode Style (fmt + clippy)check. Update that branch before merge.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/code_style.yml around lines 138 - 141, The no-code branch of the code-style workflow must propagate failures from the guidance-only fast-checks path. Update the branch around the code-style no-code handling to inspect needs.fast-checks.result and fail when it is unsuccessful, while preserving the existing behavior for successful or skipped checks.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@AGENTS.md`:
- Line 70: Update the error-propagation example in the AGENTS.md guidance to
preserve the original error source instead of converting it only with
e.to_string(). Show a thiserror variant using a #[source] field or the
repository’s established cause-preserving constructor, while retaining
contextual error propagation.
- Line 13: Update the Clippy command documentation in AGENTS.md to include
separate default-feature and --all-features invocations, retaining --all,
--benches, --tests, --examples, and -D warnings in both commands.
In `@crates/app/ironclaw_composition/src/runtime.rs`:
- Line 20: Update the module-level documentation reference in runtime.rs to
point to the owning architecture test file reborn_composition_boundaries.rs,
which contains composition_public_api_is_service_shaped and the pub_use checks,
instead of reborn_dependency_boundaries.rs.
In `@crates/substrates/ironclaw_secrets/README.md`:
- Around line 59-66: Update the Invariants section in the README to cite the
specific tests or architecture gates that enforce the secret-value, trusted-put,
isolation, and custody-only guarantees. Use existing repository references where
available; if no enforcement exists, remove or reframe those statements so they
are not presented as enforced invariants.
In `@crates/substrates/ironclaw_secrets/src/secret_store.rs`:
- Line 34: Update the documentation link in secret_store.rs to point to
../../ironclaw_filesystem/CONTRACT.md, preserving the existing invariant
reference and repository source-link convention.
In `@scripts/ci/check-guidance.py`:
- Around line 183-197: Align MIN_GUIDANCE_FILES and MIN_PATH_REFERENCES with the
stated roughly-half-of-measured-values policy by raising both constants to
appropriate thresholds based on the recorded 237 files and ~2070 references.
Keep the surrounding fail-closed rationale and other floor constants unchanged.
---
Duplicate comments:
In @.github/workflows/code_style.yml:
- Around line 138-141: The no-code branch of the code-style workflow must
propagate failures from the guidance-only fast-checks path. Update the branch
around the code-style no-code handling to inspect needs.fast-checks.result and
fail when it is unsuccessful, while preserving the existing behavior for
successful or skipped checks.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 44f2ffd3-a8da-4c81-a1ca-c4ff9a0c0a55
📒 Files selected for processing (275)
.claude/commands/deslop-reborn.md.claude/rules/database.md.claude/rules/type-placement.md.claude/rules/types.md.claude/skills/architecture-video/SKILL.md.github/workflows/code_style.ymlAGENTS.mdCLAUDE.mdCONTRIBUTING.mdcrates/AGENTS.mdcrates/CLAUDE.mdcrates/README.mdcrates/app/AGENTS.mdcrates/app/CLAUDE.mdcrates/app/ironclaw_architecture_tests/CLAUDE.mdcrates/app/ironclaw_architecture_tests/CLAUDE.mdcrates/app/ironclaw_architecture_tests/tests/reborn_authorized_seal_ratchet.rscrates/app/ironclaw_architecture_tests/tests/reborn_composition_boundaries.rscrates/app/ironclaw_architecture_tests/tests/reborn_dependency_boundaries.rscrates/app/ironclaw_architecture_tests/tests/reborn_deployment_mode_branching_ratchet.rscrates/app/ironclaw_architecture_tests/tests/reborn_extension_host_port_inversion.rscrates/app/ironclaw_architecture_tests/tests/reborn_extension_manager_split.rscrates/app/ironclaw_architecture_tests/tests/reborn_extension_specificity.rscrates/app/ironclaw_architecture_tests/tests/reborn_persistence_driver_boundary.rscrates/app/ironclaw_architecture_tests/tests/reborn_product_contract_location_scan.rscrates/app/ironclaw_architecture_tests/tests/reborn_registration_pipeline_boundary.rscrates/app/ironclaw_architecture_tests/tests/reborn_restructure_baselines.rscrates/app/ironclaw_architecture_tests/tests/reborn_same_layer_edge_inventory.rscrates/app/ironclaw_cli/CLAUDE.mdcrates/app/ironclaw_cli/src/commands/config/init.rscrates/app/ironclaw_cli/src/commands/onboard/master_key.rscrates/app/ironclaw_composition/AGENTS.mdcrates/app/ironclaw_composition/CLAUDE.mdcrates/app/ironclaw_composition/CONTRACT.mdcrates/app/ironclaw_composition/README.mdcrates/app/ironclaw_composition/src/google_oauth_secret_store.rscrates/app/ironclaw_composition/src/lib.rscrates/app/ironclaw_composition/src/observability/hooks/factory.rscrates/app/ironclaw_composition/src/observability/trajectory_observer.rscrates/app/ironclaw_composition/src/root/product_live_adapters.rscrates/app/ironclaw_composition/src/runtime.rscrates/app/ironclaw_composition/tests/provider_admin_probe.rscrates/app/ironclaw_config/AGENTS.mdcrates/app/ironclaw_config/CLAUDE.mdcrates/app/ironclaw_config/src/config_file.rscrates/contracts/CLAUDE.mdcrates/contracts/ironclaw_common/AGENTS.mdcrates/contracts/ironclaw_common/CLAUDE.mdcrates/contracts/ironclaw_extension_contracts/CLAUDE.mdcrates/contracts/ironclaw_extension_contracts/CLAUDE.mdcrates/contracts/ironclaw_extension_contracts/src/lib.rscrates/contracts/ironclaw_extension_contracts/src/verified_inbound.rscrates/contracts/ironclaw_host_api/CLAUDE.mdcrates/contracts/ironclaw_host_api/CLAUDE.mdcrates/contracts/ironclaw_host_api/src/action.rscrates/contracts/ironclaw_host_api/src/resource.rscrates/contracts/ironclaw_host_api/src/trust.rscrates/contracts/ironclaw_loop_contracts/CLAUDE.mdcrates/contracts/ironclaw_loop_contracts/CLAUDE.mdcrates/contracts/ironclaw_product_contracts/CLAUDE.mdcrates/contracts/ironclaw_product_contracts/CLAUDE.mdcrates/contracts/ironclaw_product_contracts/src/lib.rscrates/contracts/ironclaw_product_contracts/src/operator_secrets.rscrates/domains/AGENTS.mdcrates/domains/CLAUDE.mdcrates/domains/ironclaw_auth/AGENTS.mdcrates/domains/ironclaw_auth/CLAUDE.mdcrates/domains/ironclaw_auth/CLAUDE.mdcrates/domains/ironclaw_auth/README.mdcrates/domains/ironclaw_auth/src/engine/mod.rscrates/domains/ironclaw_auth/src/product_auth/mod.rscrates/domains/ironclaw_auth/tests/module_charter.rscrates/domains/ironclaw_conversations/CLAUDE.mdcrates/domains/ironclaw_conversations/CLAUDE.mdcrates/domains/ironclaw_extractors/CLAUDE.mdcrates/domains/ironclaw_identity/CONTRACT.mdcrates/domains/ironclaw_identity/src/identity_store/directory.rscrates/domains/ironclaw_llm/AGENTS.mdcrates/domains/ironclaw_llm/CLAUDE.mdcrates/domains/ironclaw_llm/CLAUDE.mdcrates/domains/ironclaw_llm/CONTRACT.mdcrates/domains/ironclaw_llm/README.mdcrates/domains/ironclaw_llm/src/error.rscrates/domains/ironclaw_llm/tests/module_charter.rscrates/domains/ironclaw_memory/CLAUDE.mdcrates/domains/ironclaw_memory/CLAUDE.mdcrates/domains/ironclaw_outbound/CLAUDE.mdcrates/domains/ironclaw_outbound/CLAUDE.mdcrates/domains/ironclaw_skills/AGENTS.mdcrates/domains/ironclaw_skills/CLAUDE.mdcrates/domains/ironclaw_skills/README.mdcrates/domains/ironclaw_threads/CLAUDE.mdcrates/domains/ironclaw_threads/CLAUDE.mdcrates/domains/ironclaw_trace_commons/AGENTS.mdcrates/domains/ironclaw_trace_commons/CLAUDE.mdcrates/domains/ironclaw_trace_commons/CLAUDE.mdcrates/domains/ironclaw_trace_commons/README.mdcrates/domains/ironclaw_triggers/CLAUDE.mdcrates/events/CLAUDE.mdcrates/events/ironclaw_event_log/CLAUDE.mdcrates/events/ironclaw_event_log/CLAUDE.mdcrates/events/ironclaw_event_projections/CLAUDE.mdcrates/events/ironclaw_event_projections/CLAUDE.mdcrates/events/ironclaw_event_store/AGENTS.mdcrates/events/ironclaw_event_store/CLAUDE.mdcrates/events/ironclaw_event_store/README.mdcrates/events/ironclaw_event_streams/CLAUDE.mdcrates/events/ironclaw_event_streams/CLAUDE.mdcrates/extensions/CLAUDE.mdcrates/extensions/ironclaw_extension_host/README.mdcrates/extensions/ironclaw_extension_host/src/channel_host/e2e_tests.rscrates/extensions/ironclaw_extension_host/src/channel_identity_store.rscrates/extensions/ironclaw_extension_host/src/test_support/first_party_registrars.rscrates/extensions/ironclaw_extension_host/tests/lifecycle_restore_contract.rscrates/extensions/ironclaw_extension_manager/AGENTS.mdcrates/extensions/ironclaw_extension_manager/CLAUDE.mdcrates/extensions/ironclaw_extension_manager/CLAUDE.mdcrates/extensions/ironclaw_extension_manager/README.mdcrates/extensions/ironclaw_extension_registry/CLAUDE.mdcrates/extensions/ironclaw_extension_registry/CLAUDE.mdcrates/extensions/ironclaw_extension_registry/tests/product_adapter_manifest_ingestion.rscrates/extensions/ironclaw_extension_support/CLAUDE.mdcrates/extensions/packages/memory-native/CLAUDE.mdcrates/extensions/packages/memory-native/CLAUDE.mdcrates/extensions/packages/memory-native/src/repo/filesystem.rscrates/extensions/packages/slack/CLAUDE.mdcrates/extensions/packages/telegram/CLAUDE.mdcrates/kernel/CLAUDE.mdcrates/kernel/ironclaw_approvals/CLAUDE.mdcrates/kernel/ironclaw_approvals/CLAUDE.mdcrates/kernel/ironclaw_authorization/CLAUDE.mdcrates/kernel/ironclaw_authorization/CLAUDE.mdcrates/kernel/ironclaw_capabilities/CLAUDE.mdcrates/kernel/ironclaw_capabilities/CLAUDE.mdcrates/kernel/ironclaw_capabilities/tests/capability_host_auth_resume_contract.rscrates/kernel/ironclaw_capabilities/tests/capability_host_invocation_state_contract.rscrates/kernel/ironclaw_host_runtime/CLAUDE.mdcrates/kernel/ironclaw_host_runtime/CLAUDE.mdcrates/kernel/ironclaw_host_runtime/tests/reborn_durable_restart_integration.rscrates/kernel/ironclaw_processes/CLAUDE.mdcrates/kernel/ironclaw_processes/CLAUDE.mdcrates/kernel/ironclaw_resources/CLAUDE.mdcrates/kernel/ironclaw_resources/CLAUDE.mdcrates/kernel/ironclaw_resources/tests/resource_governor_contract.rscrates/kernel/ironclaw_runtime_policy/CLAUDE.mdcrates/kernel/ironclaw_runtime_policy/CLAUDE.mdcrates/kernel/ironclaw_trust/CLAUDE.mdcrates/kernel/ironclaw_trust/CLAUDE.mdcrates/kernel/ironclaw_trust/src/lib.rscrates/kernel/ironclaw_turns/CLAUDE.mdcrates/kernel/ironclaw_turns/CLAUDE.mdcrates/lanes/AGENTS.mdcrates/lanes/CLAUDE.mdcrates/lanes/ironclaw_mcp/AGENTS.mdcrates/lanes/ironclaw_mcp/CLAUDE.mdcrates/lanes/ironclaw_mcp/CLAUDE.mdcrates/lanes/ironclaw_mcp/README.mdcrates/lanes/ironclaw_mcp/tests/module_charter.rscrates/lanes/ironclaw_sandbox/AGENTS.mdcrates/lanes/ironclaw_sandbox/CLAUDE.mdcrates/lanes/ironclaw_sandbox/CLAUDE.mdcrates/lanes/ironclaw_sandbox/README.mdcrates/lanes/ironclaw_sandbox/src/lib.rscrates/lanes/ironclaw_sandbox/src/sandbox_process/network_allowlist.rscrates/lanes/ironclaw_wasm/AGENTS.mdcrates/lanes/ironclaw_wasm/CLAUDE.mdcrates/lanes/ironclaw_wasm/CLAUDE.mdcrates/lanes/ironclaw_wasm/README.mdcrates/loop/CLAUDE.mdcrates/loop/ironclaw_agent_loop/CLAUDE.mdcrates/loop/ironclaw_agent_loop/CLAUDE.mdcrates/loop/ironclaw_hooks/AGENTS.mdcrates/loop/ironclaw_hooks/CLAUDE.mdcrates/loop/ironclaw_hooks/CLAUDE.mdcrates/loop/ironclaw_hooks/src/dispatch/mod.rscrates/loop/ironclaw_hooks/src/manifest.rscrates/loop/ironclaw_loop_host/CLAUDE.mdcrates/loop/ironclaw_loop_host/CLAUDE.mdcrates/loop/ironclaw_loop_host/src/await_edge_port.rscrates/loop/ironclaw_loop_host/src/thread_resolving_model_gateway.rscrates/loop/ironclaw_turn_runner/AGENTS.mdcrates/loop/ironclaw_turn_runner/CLAUDE.mdcrates/loop/ironclaw_turn_runner/CLAUDE.mdcrates/product/AGENTS.mdcrates/product/CLAUDE.mdcrates/product/ironclaw_assistant/AGENTS.mdcrates/product/ironclaw_assistant/CLAUDE.mdcrates/product/ironclaw_assistant/CLAUDE.mdcrates/product/ironclaw_assistant/README.mdcrates/product/ironclaw_assistant/src/automation_product_service/tests.rscrates/product/ironclaw_assistant/src/reborn_services.rscrates/product/ironclaw_assistant/tests/reborn_services_module_charter.rscrates/product/ironclaw_host_ingress/CLAUDE.mdcrates/product/ironclaw_host_ingress/CLAUDE.mdcrates/product/ironclaw_openai_compat/CLAUDE.mdcrates/product/ironclaw_openai_compat/CLAUDE.mdcrates/product/ironclaw_operator/CLAUDE.mdcrates/product/ironclaw_operator/CLAUDE.mdcrates/product/ironclaw_operator/src/llm_admin/llm_config_service.rscrates/product/ironclaw_operator/src/llm_admin/llm_key_store.rscrates/product/ironclaw_webui/AGENTS.mdcrates/product/ironclaw_webui/CLAUDE.mdcrates/product/ironclaw_webui/CLAUDE.mdcrates/product/ironclaw_webui/CONTRACT.mdcrates/product/ironclaw_webui/README.mdcrates/product/ironclaw_webui/src/auth/github.rscrates/product/ironclaw_webui/src/auth/pending.rscrates/product/ironclaw_webui/src/webui_body_limit.rscrates/product/ironclaw_webui/src/webui_rate_limit.rscrates/product/ironclaw_webui/src/webui_rate_limit_router_contract_test.rscrates/product/ironclaw_webui/src/webui_serve.rscrates/product/ironclaw_webui/src/webui_v2/static_assets/mod.rscrates/product/ironclaw_webui/tests/github_oauth_routes.rscrates/product/ironclaw_webui/tests/handlers_module_charter.rscrates/product/ironclaw_webui/tests/serve_loop.rscrates/substrates/CLAUDE.mdcrates/substrates/ironclaw_filesystem/AGENTS.mdcrates/substrates/ironclaw_filesystem/CLAUDE.mdcrates/substrates/ironclaw_filesystem/CLAUDE.mdcrates/substrates/ironclaw_filesystem/CONTRACT.mdcrates/substrates/ironclaw_filesystem/README.mdcrates/substrates/ironclaw_network/AGENTS.mdcrates/substrates/ironclaw_network/CLAUDE.mdcrates/substrates/ironclaw_network/README.mdcrates/substrates/ironclaw_network/src/policy.rscrates/substrates/ironclaw_network/tests/network_policy_contract.rscrates/substrates/ironclaw_observability/CLAUDE.mdcrates/substrates/ironclaw_observability/src/lib.rscrates/substrates/ironclaw_safety/CLAUDE.mdcrates/substrates/ironclaw_safety/src/leak_detector.rscrates/substrates/ironclaw_secrets/AGENTS.mdcrates/substrates/ironclaw_secrets/CLAUDE.mdcrates/substrates/ironclaw_secrets/README.mdcrates/substrates/ironclaw_secrets/src/secret_store.rsdocs/reborn/guidance-conventions.mdscripts/ci/check-guidance.pyscripts/ci/test-check-guidance.pyscripts/ci/ws12_workflow_contracts.pytests/CLAUDE.mdtests/integration/attach.rstests/integration/auth/oauth_connect.rstests/integration/extension_user_lifecycle_isolation.rstests/integration/golden_payload.rstests/integration/group_approvals/scenario_failure_category_demasked.rstests/integration/group_triggers/scenario_delivery_target_fail_closed.rstests/integration/group_triggers/scenario_triggered_gate.rstests/integration/hooks.rstests/integration/hosted_mcp_registration.rstests/integration/mcp.rstests/integration/safety.rstests/integration/support/assertions.rstests/integration/support/builder.rstests/integration/support/comm_context.rstests/integration/support/doubles/host_runtime_harness_capability_port_factory.rstests/integration/support/doubles/recording_approval_request_store.rstests/integration/support/doubles/recording_capability_result_writer.rstests/integration/support/doubles/recording_delegating_capability_port.rstests/integration/support/doubles/recording_host_runtime.rstests/integration/support/doubles/recording_network_http_egress.rstests/integration/support/doubles/recording_network_http_transport.rstests/integration/support/doubles/recording_runtime_http_egress.rstests/integration/support/group_options.rstests/integration/support/harness/mod.rstests/integration/support/harness/profiles/extension.rstests/integration/support/planned_runtime_parts_shape.rstests/integration/surface_disclosure.rstests/integration/tool_call.rstests/integration/tool_disclosure.rstests/integration/trace_capture.rstests/integration/webui_v2_product_api.rstests/integration/webui_v2_router_smoke.rstests/integration/wiring_parity.rstests/reborn_qa_channel_delivery.rstests/reborn_qa_connect_flows.rstests/reborn_qa_routines.rs
💤 Files with no reviewable changes (5)
- crates/substrates/ironclaw_network/AGENTS.md
- crates/substrates/ironclaw_secrets/AGENTS.md
- crates/substrates/ironclaw_network/CLAUDE.md
- crates/substrates/ironclaw_secrets/CLAUDE.md
- crates/domains/ironclaw_skills/AGENTS.md
| ## Discover code before changing it | ||
| ```bash | ||
| cargo fmt # format | ||
| cargo clippy --all --benches --tests --examples --all-features -- -D warnings # lint (zero warnings; CI denies warnings — an unflagged run exits 0 with them) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n -C 3 'cargo clippy|all-features|default' AGENTS.md .claude/rules .github/workflows/code_style.yml || trueRepository: nearai/ironclaw
Length of output: 22664
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo '--- AGENTS.md relevant lines ---'
sed -n '8,18p' AGENTS.md | cat -n
echo
echo '--- .github/workflows/code_style.yml clippy sections ---'
sed -n '360,422p' .github/workflows/code_style.yml | cat -n
echo
echo '--- .claude/rules/cargo-features.md relevant lines ---'
sed -n '76,88p' .claude/rules/cargo-features.md | cat -n
echo
echo '--- .claude/rules/review-discipline.md relevant lines ---'
sed -n '74,82p' .claude/rules/review-discipline.md | cat -nRepository: nearai/ironclaw
Length of output: 6716
Document both required Clippy feature lanes.
Line 6 only documents --all-features, but the repo feature-matrix invariant requires both default and all-features Clippy runs. Add the default command and keep -D warnings in both commands.
Document both lanes
- cargo clippy --all --benches --tests --examples --all-features -- -D warnings
+ cargo clippy --all --benches --tests --examples -- -D warnings
+ cargo clippy --all --benches --tests --examples --all-features -- -D warnings📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| cargo clippy --all --benches --tests --examples --all-features -- -D warnings # lint (zero warnings; CI denies warnings — an unflagged run exits 0 with them) | |
| cargo clippy --all --benches --tests --examples -- -D warnings | |
| cargo clippy --all --benches --tests --examples --all-features -- -D warnings # lint (zero warnings; CI denies warnings — an unflagged run exits 0 with them) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@AGENTS.md` at line 13, Update the Clippy command documentation in AGENTS.md
to include separate default-feature and --all-features invocations, retaining
--all, --benches, --tests, --examples, and -D warnings in both commands.
Sources: Coding guidelines, Learnings
| external boundaries. | ||
| - Shared types live with the contract owner. Do not create mirror DTOs or use | ||
| `ironclaw_common` as a general dumping ground. | ||
| - No `.unwrap()` or `.expect()` in production code (tests are fine); propagate errors with context — `.map_err(|e| SomeError::Variant { reason: e.to_string() })?` — and use `thiserror` for error types in `error.rs`. Cause-preserving constructors, the `map_err(|_| …)` ban, and the other silent-failure anti-patterns: `.claude/rules/error-handling.md`. |
There was a problem hiding this comment.
Preserve the original error source in the example.
Line 70 shows .map_err(|e| SomeError::Variant { reason: e.to_string() })?. This converts the original error to text and drops the source chain. Use a thiserror variant with a #[source] field or the repository’s cause-preserving constructor.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@AGENTS.md` at line 70, Update the error-propagation example in the AGENTS.md
guidance to preserve the original error source instead of converting it only
with e.to_string(). Show a thiserror variant using a #[source] field or the
repository’s established cause-preserving constructor, while retaining
contextual error propagation.
Sources: Coding guidelines, Path instructions
| //! `LoopExitApplier`, `HostManagedModelGateway`, etc. directly. That is the | ||
| //! property that satisfies the "narrow Reborn public surface" requirement | ||
| //! pinned by `crates/ironclaw_architecture_tests/tests/reborn_dependency_boundaries.rs`. | ||
| //! pinned by `crates/app/ironclaw_architecture_tests/tests/reborn_dependency_boundaries.rs`. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Point the reference to the owning architecture test.
Line 20 names reborn_dependency_boundaries.rs, but crates/app/ironclaw_composition/README.md lists composition_public_api_is_service_shaped and the pub_use checks in reborn_composition_boundaries.rs. Update the path so this documentation points to the gate that owns the narrow public-surface invariant.
Proposed fix
-//! pinned by `crates/app/ironclaw_architecture_tests/tests/reborn_dependency_boundaries.rs`.
+//! pinned by `crates/app/ironclaw_architecture_tests/tests/reborn_composition_boundaries.rs`.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| //! pinned by `crates/app/ironclaw_architecture_tests/tests/reborn_dependency_boundaries.rs`. | |
| //! pinned by `crates/app/ironclaw_architecture_tests/tests/reborn_composition_boundaries.rs`. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/app/ironclaw_composition/src/runtime.rs` at line 20, Update the
module-level documentation reference in runtime.rs to point to the owning
architecture test file reborn_composition_boundaries.rs, which contains
composition_public_api_is_service_shaped and the pub_use checks, instead of
reborn_dependency_boundaries.rs.
| //! Encryption-at-rest currently lives **inside this store** rather than as a | ||
| //! generic [`EncryptedBackend`] backend decorator. The | ||
| //! [`ironclaw_filesystem::CLAUDE.md`](../ironclaw_filesystem/CLAUDE.md) invariant | ||
| //! [`ironclaw_filesystem::CONTRACT.md`](../ironclaw_filesystem/CONTRACT.md) invariant |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Fix the sibling-contract link path.
From crates/substrates/ironclaw_secrets/src/secret_store.rs, ../ironclaw_filesystem/CONTRACT.md resolves under ironclaw_secrets, not to the sibling crate. Use the repository’s verified source-link convention; for a source-tree-relative link, the target is ../../ironclaw_filesystem/CONTRACT.md.
Proposed fix
-//! [`ironclaw_filesystem::CONTRACT.md`](../ironclaw_filesystem/CONTRACT.md) invariant
+//! [`ironclaw_filesystem::CONTRACT.md`](../../ironclaw_filesystem/CONTRACT.md) invariant📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| //! [`ironclaw_filesystem::CONTRACT.md`](../ironclaw_filesystem/CONTRACT.md) invariant | |
| //! [`ironclaw_filesystem::CONTRACT.md`](../../ironclaw_filesystem/CONTRACT.md) invariant |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/substrates/ironclaw_secrets/src/secret_store.rs` at line 34, Update
the documentation link in secret_store.rs to point to
../../ironclaw_filesystem/CONTRACT.md, preserving the existing invariant
reference and repository source-link convention.
| # Fail-closed floors. A scan that discovers almost no guidance files, or an | ||
| # extraction pass that finds almost no path references, means the discovery | ||
| # globs or the extractor broke — not that the repository stopped documenting | ||
| # itself. Refuse rather than report an empty scan as clean. (Measured | ||
| # 2026-08-06 on the shipped tree: 237 guidance files, ~2070 path references, | ||
| # 38 rule globs, 65 AGENTS.md/CLAUDE.md alias pairs. Re-measure with `--json` | ||
| # and re-date this comment when the numbers move materially.) Each floor sits | ||
| # roughly half of its measured value: low enough that legitimate | ||
| # consolidation never trips it, high enough that a parser or discovery pass | ||
| # silently degrading to a handful of hits refuses instead of passing — a | ||
| # floor of 1 catches only total loss, not the degraded-but-nonzero shape. | ||
| MIN_GUIDANCE_FILES = 40 | ||
| MIN_PATH_REFERENCES = 80 | ||
| MIN_RULE_GLOBS = 20 | ||
| MIN_ALIAS_PAIRS = 40 |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
The floor comment and the constants disagree.
The comment records 237 guidance files and ~2070 path references, then states each floor sits at roughly half its measured value. MIN_GUIDANCE_FILES = 40 is 17% of measured, and MIN_PATH_REFERENCES = 80 is 4%. A discovery pass that degrades from 237 files to 45, or an extractor that degrades from 2070 references to 90, still passes — the exact degraded-but-nonzero shape this comment says the floors exist to catch. Either raise both constants toward half, or correct the prose so a later maintainer does not trust a guarantee the numbers do not provide.
♻️ Proposed floors
-MIN_GUIDANCE_FILES = 40
-MIN_PATH_REFERENCES = 80
+MIN_GUIDANCE_FILES = 120
+MIN_PATH_REFERENCES = 1000
MIN_RULE_GLOBS = 20
MIN_ALIAS_PAIRS = 40📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Fail-closed floors. A scan that discovers almost no guidance files, or an | |
| # extraction pass that finds almost no path references, means the discovery | |
| # globs or the extractor broke — not that the repository stopped documenting | |
| # itself. Refuse rather than report an empty scan as clean. (Measured | |
| # 2026-08-06 on the shipped tree: 237 guidance files, ~2070 path references, | |
| # 38 rule globs, 65 AGENTS.md/CLAUDE.md alias pairs. Re-measure with `--json` | |
| # and re-date this comment when the numbers move materially.) Each floor sits | |
| # roughly half of its measured value: low enough that legitimate | |
| # consolidation never trips it, high enough that a parser or discovery pass | |
| # silently degrading to a handful of hits refuses instead of passing — a | |
| # floor of 1 catches only total loss, not the degraded-but-nonzero shape. | |
| MIN_GUIDANCE_FILES = 40 | |
| MIN_PATH_REFERENCES = 80 | |
| MIN_RULE_GLOBS = 20 | |
| MIN_ALIAS_PAIRS = 40 | |
| # Fail-closed floors. A scan that discovers almost no guidance files, or an | |
| # extraction pass that finds almost no path references, means the discovery | |
| # globs or the extractor broke — not that the repository stopped documenting | |
| # itself. Refuse rather than report an empty scan as clean. (Measured | |
| # 2026-08-06 on the shipped tree: 237 guidance files, ~2070 path references, | |
| # 38 rule globs, 65 AGENTS.md/CLAUDE.md alias pairs. Re-measure with `--json` | |
| # and re-date this comment when the numbers move materially.) Each floor sits | |
| # roughly half of its measured value: low enough that legitimate | |
| # consolidation never trips it, high enough that a parser or discovery pass | |
| # silently degrading to a handful of hits refuses instead of passing — a | |
| # floor of 1 catches only total loss, not the degraded-but-nonzero shape. | |
| MIN_GUIDANCE_FILES = 120 | |
| MIN_PATH_REFERENCES = 1000 | |
| MIN_RULE_GLOBS = 20 | |
| MIN_ALIAS_PAIRS = 40 |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/ci/check-guidance.py` around lines 183 - 197, Align
MIN_GUIDANCE_FILES and MIN_PATH_REFERENCES with the stated
roughly-half-of-measured-values policy by raising both constants to appropriate
thresholds based on the recorded 237 files and ~2070 references. Keep the
surrounding fail-closed rationale and other floor constants unchanged.
Six conflicts. Structure follows this branch; main's content ported: - ironclaw_assistant/CLAUDE.md stays a symlink; main's #7235 edits (reborn_services.rs 7,354 lines, new 'inspector' charter row) landed in AGENTS.md. - ironclaw_webui/CLAUDE.md stays a symlink; main's inspector route-table row (webui.v2.operator.inspector_*) landed in CONTRACT.md. - ironclaw_filesystem/CLAUDE.md stays a symlink; main's two docs/internal/plans/2026-06-25-cas-migration.md reference fixes landed in CONTRACT.md. - code_style.yml: union — has_guidance (ours) and has_docs (#7259) both kept. - root AGENTS.md: ours kept; main's docs/ publication-boundary paragraph ported into the Project structure section (mirrors main's own CLAUDE.md placement). - root CLAUDE.md: ours kept (@AGENTS.md + Claude tail); main's short docs note flows in via the AGENTS.md embed. docs/plans -> docs/internal/plans sweep: only the two CONTRACT.md references above dangled; repo-wide rg for every #7259-moved path is clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… -> 97 #7236 (main) added the four operator inspector routes without bumping the stated counts; re-derived on the merged tree: rg -c 'pub const WEBUI_V2_ROUTE_' crates/product/ironclaw_webui/src/webui_v2/descriptors.rs -> 97. Updates the two live claims (webui README, PROPOSAL SS6.9.4 with its strike-through recount convention); historical/superseded 92-row mentions stay as written. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
…nly PRs The has_guidance trigger made fast-checks RUN for .claude/ and root-pair changes, but the roll-up's has_code==false branch exits 0 before it ever reads fast-checks' result — so check-guidance.py could fail and Code Style would still report success. The gate ran and could never block: exactly the inert-guard shape this change exists to remove, reintroduced one layer up. Fixed the way main's docs-publication gate already does it — judged before the early exit, with the reason in a comment. Sabotage-verified: has_guidance=true plus fast-checks=failure now exits 1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
AGENTS.md (1)
13-13:⚠️ Potential issue | 🟡 MinorAdd the default-feature Clippy lane.
Line [13] documents only
--all-features. The repository's required validation uses one default-feature run and one--all-featuresrun. An all-features-only run can hidecfg-specific code. Add the default command and retain-- -D warningsin both commands.Based on learnings: Clippy review requires separate default-feature and all-features lanes.
Proposed documentation update
- cargo clippy --all --benches --tests --examples --all-features -- -D warnings + cargo clippy --all --benches --tests --examples -- -D warnings + cargo clippy --all --benches --tests --examples --all-features -- -D warnings🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@AGENTS.md` at line 13, Update the Clippy validation documentation in AGENTS.md to list separate default-feature and --all-features commands, retaining -- -D warnings for both lanes. Keep the existing all-features command and add the equivalent command without --all-features so cfg-specific code is checked.Source: Learnings
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/product/ironclaw_assistant/AGENTS.md`:
- Line 351: Update the Clippy validation commands in the documentation around
the existing `cargo clippy` checks to add the required `--all-targets
--all-features -- -D warnings` lane beside the default-feature lane. Preserve
the separate production-shape Clippy command without dev-dependencies if it
remains required.
In `@crates/product/ironclaw_webui/CONTRACT.md`:
- Around line 366-368: Replace the insecure ID-token decoding in GoogleProvider
with JWT signature verification using Google’s JWKS, while retaining issuer,
audience, and expiration validation. Update CONTRACT.md to remove the claim that
TLS substitutes for signature checks, and add a regression test proving
signed-token verification is required.
In `@crates/substrates/ironclaw_network/README.md`:
- Around line 56-60: Document exact executable test or architecture-gate
references for every claimed invariant: in
crates/substrates/ironclaw_network/README.md lines 56-60, cite coverage for
scope preservation and mechanism-only ownership; in
crates/substrates/ironclaw_secrets/README.md lines 59-66, cite coverage for
one-shot consumption, output redaction, trusted put, scope isolation, and
custody-only boundaries. Reframe any claim lacking current enforcement rather
than presenting it as an enforced invariant.
In `@docs/reborn/guidance-conventions.md`:
- Around line 172-175: Update the line-count annotation for
crates/product/ironclaw_assistant/AGENTS.md in the guidance conventions entry
from 358 to the file’s measured count of 359, preserving the surrounding
description and formatting.
---
Duplicate comments:
In `@AGENTS.md`:
- Line 13: Update the Clippy validation documentation in AGENTS.md to list
separate default-feature and --all-features commands, retaining -- -D warnings
for both lanes. Keep the existing all-features command and add the equivalent
command without --all-features so cfg-specific code is checked.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: d8bc2a11-b925-4de7-94af-6730cee333ca
📒 Files selected for processing (275)
.claude/commands/deslop-reborn.md.claude/rules/database.md.claude/rules/type-placement.md.claude/rules/types.md.claude/skills/architecture-video/SKILL.md.github/workflows/code_style.ymlAGENTS.mdCLAUDE.mdCONTRIBUTING.mdcrates/AGENTS.mdcrates/CLAUDE.mdcrates/README.mdcrates/app/AGENTS.mdcrates/app/CLAUDE.mdcrates/app/ironclaw_architecture_tests/CLAUDE.mdcrates/app/ironclaw_architecture_tests/CLAUDE.mdcrates/app/ironclaw_architecture_tests/tests/reborn_authorized_seal_ratchet.rscrates/app/ironclaw_architecture_tests/tests/reborn_composition_boundaries.rscrates/app/ironclaw_architecture_tests/tests/reborn_dependency_boundaries.rscrates/app/ironclaw_architecture_tests/tests/reborn_deployment_mode_branching_ratchet.rscrates/app/ironclaw_architecture_tests/tests/reborn_extension_host_port_inversion.rscrates/app/ironclaw_architecture_tests/tests/reborn_extension_manager_split.rscrates/app/ironclaw_architecture_tests/tests/reborn_extension_specificity.rscrates/app/ironclaw_architecture_tests/tests/reborn_persistence_driver_boundary.rscrates/app/ironclaw_architecture_tests/tests/reborn_product_contract_location_scan.rscrates/app/ironclaw_architecture_tests/tests/reborn_registration_pipeline_boundary.rscrates/app/ironclaw_architecture_tests/tests/reborn_restructure_baselines.rscrates/app/ironclaw_architecture_tests/tests/reborn_same_layer_edge_inventory.rscrates/app/ironclaw_cli/CLAUDE.mdcrates/app/ironclaw_cli/src/commands/config/init.rscrates/app/ironclaw_cli/src/commands/onboard/master_key.rscrates/app/ironclaw_composition/AGENTS.mdcrates/app/ironclaw_composition/CLAUDE.mdcrates/app/ironclaw_composition/CONTRACT.mdcrates/app/ironclaw_composition/README.mdcrates/app/ironclaw_composition/src/google_oauth_secret_store.rscrates/app/ironclaw_composition/src/lib.rscrates/app/ironclaw_composition/src/observability/hooks/factory.rscrates/app/ironclaw_composition/src/observability/trajectory_observer.rscrates/app/ironclaw_composition/src/root/product_live_adapters.rscrates/app/ironclaw_composition/src/runtime.rscrates/app/ironclaw_composition/tests/provider_admin_probe.rscrates/app/ironclaw_config/AGENTS.mdcrates/app/ironclaw_config/CLAUDE.mdcrates/app/ironclaw_config/src/config_file.rscrates/contracts/CLAUDE.mdcrates/contracts/ironclaw_common/AGENTS.mdcrates/contracts/ironclaw_common/CLAUDE.mdcrates/contracts/ironclaw_extension_contracts/CLAUDE.mdcrates/contracts/ironclaw_extension_contracts/CLAUDE.mdcrates/contracts/ironclaw_extension_contracts/src/lib.rscrates/contracts/ironclaw_extension_contracts/src/verified_inbound.rscrates/contracts/ironclaw_host_api/CLAUDE.mdcrates/contracts/ironclaw_host_api/CLAUDE.mdcrates/contracts/ironclaw_host_api/src/action.rscrates/contracts/ironclaw_host_api/src/resource.rscrates/contracts/ironclaw_host_api/src/trust.rscrates/contracts/ironclaw_loop_contracts/CLAUDE.mdcrates/contracts/ironclaw_loop_contracts/CLAUDE.mdcrates/contracts/ironclaw_product_contracts/CLAUDE.mdcrates/contracts/ironclaw_product_contracts/CLAUDE.mdcrates/contracts/ironclaw_product_contracts/src/lib.rscrates/contracts/ironclaw_product_contracts/src/operator_secrets.rscrates/domains/AGENTS.mdcrates/domains/CLAUDE.mdcrates/domains/ironclaw_auth/AGENTS.mdcrates/domains/ironclaw_auth/CLAUDE.mdcrates/domains/ironclaw_auth/CLAUDE.mdcrates/domains/ironclaw_auth/README.mdcrates/domains/ironclaw_auth/src/engine/mod.rscrates/domains/ironclaw_auth/src/product_auth/mod.rscrates/domains/ironclaw_auth/tests/module_charter.rscrates/domains/ironclaw_conversations/CLAUDE.mdcrates/domains/ironclaw_conversations/CLAUDE.mdcrates/domains/ironclaw_extractors/CLAUDE.mdcrates/domains/ironclaw_identity/CONTRACT.mdcrates/domains/ironclaw_identity/src/identity_store/directory.rscrates/domains/ironclaw_llm/AGENTS.mdcrates/domains/ironclaw_llm/CLAUDE.mdcrates/domains/ironclaw_llm/CLAUDE.mdcrates/domains/ironclaw_llm/CONTRACT.mdcrates/domains/ironclaw_llm/README.mdcrates/domains/ironclaw_llm/src/error.rscrates/domains/ironclaw_llm/tests/module_charter.rscrates/domains/ironclaw_memory/CLAUDE.mdcrates/domains/ironclaw_memory/CLAUDE.mdcrates/domains/ironclaw_outbound/CLAUDE.mdcrates/domains/ironclaw_outbound/CLAUDE.mdcrates/domains/ironclaw_skills/AGENTS.mdcrates/domains/ironclaw_skills/CLAUDE.mdcrates/domains/ironclaw_skills/README.mdcrates/domains/ironclaw_threads/CLAUDE.mdcrates/domains/ironclaw_threads/CLAUDE.mdcrates/domains/ironclaw_trace_commons/AGENTS.mdcrates/domains/ironclaw_trace_commons/CLAUDE.mdcrates/domains/ironclaw_trace_commons/CLAUDE.mdcrates/domains/ironclaw_trace_commons/README.mdcrates/domains/ironclaw_triggers/CLAUDE.mdcrates/events/CLAUDE.mdcrates/events/ironclaw_event_log/CLAUDE.mdcrates/events/ironclaw_event_log/CLAUDE.mdcrates/events/ironclaw_event_projections/CLAUDE.mdcrates/events/ironclaw_event_projections/CLAUDE.mdcrates/events/ironclaw_event_store/AGENTS.mdcrates/events/ironclaw_event_store/CLAUDE.mdcrates/events/ironclaw_event_store/README.mdcrates/events/ironclaw_event_streams/CLAUDE.mdcrates/events/ironclaw_event_streams/CLAUDE.mdcrates/extensions/CLAUDE.mdcrates/extensions/ironclaw_extension_host/README.mdcrates/extensions/ironclaw_extension_host/src/channel_host/e2e_tests.rscrates/extensions/ironclaw_extension_host/src/channel_identity_store.rscrates/extensions/ironclaw_extension_host/src/test_support/first_party_registrars.rscrates/extensions/ironclaw_extension_host/tests/lifecycle_restore_contract.rscrates/extensions/ironclaw_extension_manager/AGENTS.mdcrates/extensions/ironclaw_extension_manager/CLAUDE.mdcrates/extensions/ironclaw_extension_manager/CLAUDE.mdcrates/extensions/ironclaw_extension_manager/README.mdcrates/extensions/ironclaw_extension_registry/CLAUDE.mdcrates/extensions/ironclaw_extension_registry/CLAUDE.mdcrates/extensions/ironclaw_extension_registry/tests/product_adapter_manifest_ingestion.rscrates/extensions/ironclaw_extension_support/CLAUDE.mdcrates/extensions/packages/memory-native/CLAUDE.mdcrates/extensions/packages/memory-native/CLAUDE.mdcrates/extensions/packages/memory-native/src/repo/filesystem.rscrates/extensions/packages/slack/CLAUDE.mdcrates/extensions/packages/telegram/CLAUDE.mdcrates/kernel/CLAUDE.mdcrates/kernel/ironclaw_approvals/CLAUDE.mdcrates/kernel/ironclaw_approvals/CLAUDE.mdcrates/kernel/ironclaw_authorization/CLAUDE.mdcrates/kernel/ironclaw_authorization/CLAUDE.mdcrates/kernel/ironclaw_capabilities/CLAUDE.mdcrates/kernel/ironclaw_capabilities/CLAUDE.mdcrates/kernel/ironclaw_capabilities/tests/capability_host_auth_resume_contract.rscrates/kernel/ironclaw_capabilities/tests/capability_host_invocation_state_contract.rscrates/kernel/ironclaw_host_runtime/CLAUDE.mdcrates/kernel/ironclaw_host_runtime/CLAUDE.mdcrates/kernel/ironclaw_host_runtime/tests/reborn_durable_restart_integration.rscrates/kernel/ironclaw_processes/CLAUDE.mdcrates/kernel/ironclaw_processes/CLAUDE.mdcrates/kernel/ironclaw_resources/CLAUDE.mdcrates/kernel/ironclaw_resources/CLAUDE.mdcrates/kernel/ironclaw_resources/tests/resource_governor_contract.rscrates/kernel/ironclaw_runtime_policy/CLAUDE.mdcrates/kernel/ironclaw_runtime_policy/CLAUDE.mdcrates/kernel/ironclaw_trust/CLAUDE.mdcrates/kernel/ironclaw_trust/CLAUDE.mdcrates/kernel/ironclaw_trust/src/lib.rscrates/kernel/ironclaw_turns/CLAUDE.mdcrates/kernel/ironclaw_turns/CLAUDE.mdcrates/lanes/AGENTS.mdcrates/lanes/CLAUDE.mdcrates/lanes/ironclaw_mcp/AGENTS.mdcrates/lanes/ironclaw_mcp/CLAUDE.mdcrates/lanes/ironclaw_mcp/CLAUDE.mdcrates/lanes/ironclaw_mcp/README.mdcrates/lanes/ironclaw_mcp/tests/module_charter.rscrates/lanes/ironclaw_sandbox/AGENTS.mdcrates/lanes/ironclaw_sandbox/CLAUDE.mdcrates/lanes/ironclaw_sandbox/CLAUDE.mdcrates/lanes/ironclaw_sandbox/README.mdcrates/lanes/ironclaw_sandbox/src/lib.rscrates/lanes/ironclaw_sandbox/src/sandbox_process/network_allowlist.rscrates/lanes/ironclaw_wasm/AGENTS.mdcrates/lanes/ironclaw_wasm/CLAUDE.mdcrates/lanes/ironclaw_wasm/CLAUDE.mdcrates/lanes/ironclaw_wasm/README.mdcrates/loop/CLAUDE.mdcrates/loop/ironclaw_agent_loop/CLAUDE.mdcrates/loop/ironclaw_agent_loop/CLAUDE.mdcrates/loop/ironclaw_hooks/AGENTS.mdcrates/loop/ironclaw_hooks/CLAUDE.mdcrates/loop/ironclaw_hooks/CLAUDE.mdcrates/loop/ironclaw_hooks/src/dispatch/mod.rscrates/loop/ironclaw_hooks/src/manifest.rscrates/loop/ironclaw_loop_host/CLAUDE.mdcrates/loop/ironclaw_loop_host/CLAUDE.mdcrates/loop/ironclaw_loop_host/src/await_edge_port.rscrates/loop/ironclaw_loop_host/src/thread_resolving_model_gateway.rscrates/loop/ironclaw_turn_runner/AGENTS.mdcrates/loop/ironclaw_turn_runner/CLAUDE.mdcrates/loop/ironclaw_turn_runner/CLAUDE.mdcrates/product/AGENTS.mdcrates/product/CLAUDE.mdcrates/product/ironclaw_assistant/AGENTS.mdcrates/product/ironclaw_assistant/CLAUDE.mdcrates/product/ironclaw_assistant/CLAUDE.mdcrates/product/ironclaw_assistant/README.mdcrates/product/ironclaw_assistant/src/automation_product_service/tests.rscrates/product/ironclaw_assistant/src/reborn_services.rscrates/product/ironclaw_assistant/tests/reborn_services_module_charter.rscrates/product/ironclaw_host_ingress/CLAUDE.mdcrates/product/ironclaw_host_ingress/CLAUDE.mdcrates/product/ironclaw_openai_compat/CLAUDE.mdcrates/product/ironclaw_openai_compat/CLAUDE.mdcrates/product/ironclaw_operator/CLAUDE.mdcrates/product/ironclaw_operator/CLAUDE.mdcrates/product/ironclaw_operator/src/llm_admin/llm_config_service.rscrates/product/ironclaw_operator/src/llm_admin/llm_key_store.rscrates/product/ironclaw_webui/AGENTS.mdcrates/product/ironclaw_webui/CLAUDE.mdcrates/product/ironclaw_webui/CLAUDE.mdcrates/product/ironclaw_webui/CONTRACT.mdcrates/product/ironclaw_webui/README.mdcrates/product/ironclaw_webui/src/auth/github.rscrates/product/ironclaw_webui/src/auth/pending.rscrates/product/ironclaw_webui/src/webui_body_limit.rscrates/product/ironclaw_webui/src/webui_rate_limit.rscrates/product/ironclaw_webui/src/webui_rate_limit_router_contract_test.rscrates/product/ironclaw_webui/src/webui_serve.rscrates/product/ironclaw_webui/src/webui_v2/static_assets/mod.rscrates/product/ironclaw_webui/tests/github_oauth_routes.rscrates/product/ironclaw_webui/tests/handlers_module_charter.rscrates/product/ironclaw_webui/tests/serve_loop.rscrates/substrates/CLAUDE.mdcrates/substrates/ironclaw_filesystem/AGENTS.mdcrates/substrates/ironclaw_filesystem/CLAUDE.mdcrates/substrates/ironclaw_filesystem/CLAUDE.mdcrates/substrates/ironclaw_filesystem/CONTRACT.mdcrates/substrates/ironclaw_filesystem/README.mdcrates/substrates/ironclaw_network/AGENTS.mdcrates/substrates/ironclaw_network/CLAUDE.mdcrates/substrates/ironclaw_network/README.mdcrates/substrates/ironclaw_network/src/policy.rscrates/substrates/ironclaw_network/tests/network_policy_contract.rscrates/substrates/ironclaw_observability/CLAUDE.mdcrates/substrates/ironclaw_observability/src/lib.rscrates/substrates/ironclaw_safety/CLAUDE.mdcrates/substrates/ironclaw_safety/src/leak_detector.rscrates/substrates/ironclaw_secrets/AGENTS.mdcrates/substrates/ironclaw_secrets/CLAUDE.mdcrates/substrates/ironclaw_secrets/README.mdcrates/substrates/ironclaw_secrets/src/secret_store.rsdocs/reborn/guidance-conventions.mddocs/reborn/target-architecture/PROPOSAL.mdscripts/ci/check-guidance.pyscripts/ci/test-check-guidance.pyscripts/ci/ws12_workflow_contracts.pytests/CLAUDE.mdtests/integration/attach.rstests/integration/auth/oauth_connect.rstests/integration/extension_user_lifecycle_isolation.rstests/integration/golden_payload.rstests/integration/group_approvals/scenario_failure_category_demasked.rstests/integration/group_triggers/scenario_delivery_target_fail_closed.rstests/integration/group_triggers/scenario_triggered_gate.rstests/integration/hooks.rstests/integration/hosted_mcp_registration.rstests/integration/mcp.rstests/integration/safety.rstests/integration/support/assertions.rstests/integration/support/builder.rstests/integration/support/comm_context.rstests/integration/support/doubles/host_runtime_harness_capability_port_factory.rstests/integration/support/doubles/recording_approval_request_store.rstests/integration/support/doubles/recording_capability_result_writer.rstests/integration/support/doubles/recording_delegating_capability_port.rstests/integration/support/doubles/recording_host_runtime.rstests/integration/support/doubles/recording_network_http_egress.rstests/integration/support/doubles/recording_network_http_transport.rstests/integration/support/doubles/recording_runtime_http_egress.rstests/integration/support/harness/mod.rstests/integration/support/harness/profiles/extension.rstests/integration/support/planned_runtime_parts_shape.rstests/integration/surface_disclosure.rstests/integration/tool_call.rstests/integration/tool_disclosure.rstests/integration/trace_capture.rstests/integration/webui_v2_product_api.rstests/integration/webui_v2_router_smoke.rstests/integration/wiring_parity.rstests/reborn_qa_channel_delivery.rstests/reborn_qa_connect_flows.rstests/reborn_qa_routines.rs
💤 Files with no reviewable changes (5)
- crates/substrates/ironclaw_secrets/CLAUDE.md
- crates/substrates/ironclaw_secrets/AGENTS.md
- crates/domains/ironclaw_skills/AGENTS.md
- crates/substrates/ironclaw_network/CLAUDE.md
- crates/substrates/ironclaw_network/AGENTS.md
| - Fast local check: `cargo test -p ironclaw_assistant` | ||
| - Lint check: `cargo clippy -p ironclaw_assistant --all-targets -- -D warnings` | ||
| - Boundary check after dependency/API changes: `cargo test -p ironclaw_architecture_tests reborn_crate_dependency_boundaries_hold` | ||
| - Lint check: `cargo clippy -p ironclaw_assistant --all-targets -- -D warnings` (the self dev-dependency unifies `test-support` on, so this lints the feature-on shape) plus the production shape with dev-dependencies off: `cargo clippy -p ironclaw_assistant -- -D warnings` (mirrors the merge-queue `--lib --bins` lane; the #7119 unused-import class is only visible here) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add the required all-features Clippy lane.
The documented commands omit --all-features. Add the all-features lane beside the default-feature lane. Keep the production-shape check if it is still required.
Suggested validation update
cargo clippy -p ironclaw_assistant --all-targets -- -D warnings
+ cargo clippy -p ironclaw_assistant --all-targets --all-features -- -D warningsAs per coding guidelines, changed Reborn crates must pass Clippy with --all-targets --all-features -- -D warnings.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/product/ironclaw_assistant/AGENTS.md` at line 351, Update the Clippy
validation commands in the documentation around the existing `cargo clippy`
checks to add the required `--all-targets --all-features -- -D warnings` lane
beside the default-feature lane. Preserve the separate production-shape Clippy
command without dev-dependencies if it remains required.
Source: Coding guidelines
| claim check, audience+issuer validation; signature verification | ||
| is disabled because the `id_token` arrived over TLS directly | ||
| from Google). |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 8 \
'GoogleProvider|id_token|DecodingKey|JWKS|Jwk|signature' \
crates/product/ironclaw_webui/src/auth \
|| trueRepository: nearai/ironclaw
Length of output: 43320
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== relevant contract section =="
sed -n '350,375p' crates/product/ironclaw_webui/CONTRACT.md
echo "== google id token decode implementation =="
sed -n '1e5p' crates/product/ironclaw_webui/src/auth/google.rs
echo "== deterministic check: implementation uses dangerous insecure_decode and token signature is fake in tests =="
python3 - <<'PY'
from pathlib import Path
src = Path("crates/product/ironclaw_webui/src/auth/google.rs").read_text()
contract = Path("crates/product/ironclaw_webui/CONTRACT.md").read_text()
checks = {
"uses_dangerous_insecure_decode": "jsonwebtoken::dangerous::insecure_decode" in src,
"doc_says_skip_signature_verification_tls": "token arrived over TLS directly from Google" in src,
"contract_says_signature_verification_disabled_tls": "signature verification" in contract[contract.find("audience+issuer"):contract.find("audience+issuer")+300],
"mock_token_fake_signature": 'format!("{header}.{claims}.signature")' in src,
}
for k,v in checks.items():
print(f"{k}: {v}")
PYRepository: nearai/ironclaw
Length of output: 1696
No signature verification in Google ID-token validation.
GoogleProvider decodes ID tokens with jsonwebtoken::dangerous::insecure_decode, and both the implementation and CONTRACT.md state TLS substitutes for signature validation. TLS protects transport only; require JWT signature verification against Google’s JWKS in addition to iss, aud, and expiration checks. Add a regression guard for signed tokens so this pre-existing WebUI auth gap does not reappear.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/product/ironclaw_webui/CONTRACT.md` around lines 366 - 368, Replace
the insecure ID-token decoding in GoogleProvider with JWT signature verification
using Google’s JWKS, while retaining issuer, audience, and expiration
validation. Update CONTRACT.md to remove the claim that TLS substitutes for
signature checks, and add a regression test proving signed-token verification is
required.
Sources: Path instructions, Learnings
| - **Scope travels intact:** tenant/user/agent/project scope is preserved in | ||
| requests, permits, and errors. | ||
| - **Mechanism only:** no secret injection, resource reservation, audit/event | ||
| emission, authorization/approval decisions, or product workflow here — those | ||
| belong to the kernel and the owning domains. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Document the enforcement for each new invariant.
Both README changes present boundary and security claims as enforced invariants without naming the executable tests or architecture gates that prove them. Add exact enforcement references, or reframe claims that are not currently enforced.
crates/substrates/ironclaw_network/README.md#L56-L60: cite coverage for scope preservation and mechanism-only ownership.crates/substrates/ironclaw_secrets/README.md#L59-L66: cite coverage for one-shot consumption, output redaction, trustedput, scope isolation, and custody-only boundaries.
📍 Affects 2 files
crates/substrates/ironclaw_network/README.md#L56-L60(this comment)crates/substrates/ironclaw_secrets/README.md#L59-L66
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/substrates/ironclaw_network/README.md` around lines 56 - 60, Document
exact executable test or architecture-gate references for every claimed
invariant: in crates/substrates/ironclaw_network/README.md lines 56-60, cite
coverage for scope preservation and mechanism-only ownership; in
crates/substrates/ironclaw_secrets/README.md lines 59-66, cite coverage for
one-shot consumption, output redaction, trusted put, scope isolation, and
custody-only boundaries. Reframe any claim lacking current enforcement rather
than presenting it as an enforced invariant.
| - `crates/product/ironclaw_assistant/AGENTS.md` (358) — carries the | ||
| gate-pinned `reborn_services` module-charter map, machine-parsed by | ||
| `tests/reborn_services_module_charter.rs`, which must not be reflowed; | ||
| boundary rules and the trigger-thread exception fill the rest. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Correct the measured line count.
At Line 172, the exception records crates/product/ironclaw_assistant/AGENTS.md as 358 lines. The supplied file reaches Line 359 before its trailing blank line. Update the recorded measurement or regenerate it from the file.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/reborn/guidance-conventions.md` around lines 172 - 175, Update the
line-count annotation for crates/product/ironclaw_assistant/AGENTS.md in the
guidance conventions entry from 358 to the file’s measured count of 359,
preserving the surrounding description and formatting.
…story, and a gate that keeps it true (nearai#7306) * ci(guidance): add check-guidance.py — guidance must reference the tree that exists Four mechanical drift classes become build failures: every repo path named by agent guidance (root AGENTS.md/CLAUDE.md, crates/** AGENTS/CLAUDE/ CONTRACT/README, .claude/rules/*.md, .claude/skills/*/SKILL.md) must resolve in the tracked tree; every rules/skills frontmatter paths: glob must match at least one tracked file (the dead-trigger class that let skills.md never fire); every crate directory appears in its family's AGENTS.md crate table (the guidance half of check-target-tree.py); and every crate has a README.md (measured 62/62, so it gates). Extraction is designed against false positives: fenced blocks, placeholder tokens, MCP method names, dated-correction (✎) lines, and 'check-guidance: path-ok' lines are not claims; resolution honors the citation forms measured on the live tree (root-relative, doc-relative, name-prefix, crate-qualified-by-context, module-relative within the citing crate). KNOWN_MISSING is a shrink-only suppression table — a row whose reference stops dangling fails the gate until deleted, and surviving rows print as warnings every run. Fails closed on unreadable files, unparseable frontmatter, broken crate discovery, and near-empty scans (floor constants). Self-test in test-check-guidance.py (23 cases, refusals first, real repository last), wired beside check-target-tree.py in code_style.yml; the test planner classifies all three paths as static-control (verified exit 0). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(guidance): consolidate crate-tier CLAUDE.md files; rename module specs to CONTRACT.md Steps 2+3 of the guidance unification (docs/reborn/guidance-conventions.md): - Rename the four Module Specs table specs CLAUDE.md -> CONTRACT.md (llm, filesystem, webui, composition), matching the identity/trust precedent. Charter gates repointed (llm module_charter, webui handlers_module_charter) and every live reference updated; pointer stubs left behind so tooling that loads CLAUDE.md still lands on the spec. - Fold the nine substantive out-of-table CLAUDE.md files: wasm, mcp, sandbox, auth, assistant, trace_commons, extension_manager become AGENTS.md-canonical (gates repointed with pinned phrases kept verbatim: the wasm_sandbox_core arch pin, mcp module_charter, auth module_charter, assistant reborn_services_module_charter); network and secrets fold into their README Invariants sections and drop the crate guidance pair entirely. - Mark with the convention's absence-claim annotation the five crate-tier lines grandfathered by check-guidance KNOWN_MISSING (llm CONTRACT.md x3, composition CONTRACT.md, hooks AGENTS.md) and mark trace_commons' prescribed tests/queue.rs mirror as prescriptive-future. - tests/CLAUDE.md: replace the retired root Current-Limitations citation with the measured ironclaw_observability description. End state: zero prose CLAUDE.md outside the Module Specs table at the crate tier (the four ironclaw_agent_loop src/tests directory guides stay, same footing as the tests-tree harness guides). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(guidance): unify the root pair — AGENTS.md canonical, CLAUDE.md adapter Step 1: root AGENTS.md (198 lines) and root CLAUDE.md (286 lines) shared zero identical lines — the forked-pair drift the guidance convention forbids at crate level, live at the root. Root AGENTS.md is now the canonical tool-neutral contract (build/run/debug commands, hard invariants including the unified extension model and the credential_name/extension_name identity rules, the Module Specs table — now uniformly CONTRACT.md and gaining the existing ironclaw_trust/CONTRACT.md row — testing discipline, tree map, discovery, change discipline; 152 lines). Root CLAUDE.md is an @AGENTS.md adapter plus the genuinely Claude-specific tail: skills/rules index, codebase-graph MCP recipes, and the REPL info!/warn! logging rule (51 lines). Cut while merging, each measured against the tree: the v1 Job State Machine (no such state machine exists under crates/), Current Limitations (stale — the observability claim no longer matches the crate), the Skills System section (.claude/rules/skills.md and the domain crate own it), Extracted Crates, the re-derivable key-traits list, and the long channel-onboarding narrative (now three lines pointing at crates/extensions/AGENTS.md and the worked slack example). Every live citation of the root pair's moved sections is repointed (crates/ routing map + README, the deslop-reborn command, types/type-placement rules, skills/common/config crate docs, a loop_host doc comment). The git-ignored .codebase-memory/artifact.json mention carries the absence-claim annotation for the check-guidance KNOWN_MISSING handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(guidance): make CLAUDE.md a symlink to AGENTS.md at every tier The loader question is now measured, not assumed. Headless canary experiment with a discriminating control: a symlinked nested CLAUDE.md's target content IS injected when a file in that directory is read, an @AGENTS.md import inside a nested CLAUDE.md also expands, and a nested AGENTS.md alone is NOT read. So one uniform rule holds everywhere: wherever an AGENTS.md exists, CLAUDE.md sits beside it as a symlink — same bytes, zero maintenance, no second document to drift. 64 pointer stubs become symlinks. The four spec crates keep CONTRACT.md as canonical; their AGENTS.md routes there, so the spec stays one hop away while the working rules now auto-inject instead of costing a voluntary read. Also reconciled check-guidance.py's shrink-only KNOWN_MISSING table: all 8 rows deleted because the content pass fixed the underlying lines, and the three absence-claims the gate then surfaced carry markers. The table is empty. Caveat recorded for the convention: nested injection fires only below cwd, and appears not to fire in subagent sessions — family docs must stand alone when read deliberately. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(guidance): amend the convention with measured loader mechanics and budgets The first version made crate AGENTS.md canonical and CLAUDE.md a pointer, which moved working rules out of Claude Code's auto-inject path. Records what was measured instead: subtree CLAUDE.md injects lazily, symlinks and @imports both carry content, nested AGENTS.md is not read natively, and injection does not fire in subagent sessions — so every doc must stand alone when read deliberately. Adds size budgets per tier, extends scope to .claude/rules and .claude/skills (where the worst drift was), names check-guidance.py as the enforcement with its suppression markers, warns that some guidance is test-parsed (including the heading-shadowing trap), and adds the remove/rename checklist that mirrors add. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(guidance): composition keeps a real CLAUDE.md, not a symlink The blanket symlink pass broke composition_root_embeds_no_prompt_content, and the gate is right to refuse: its ownership walks do not follow symlinks, so stepping over one would let it report clean on a subtree it never read. This crate keeps a regular pointer file, with the reason written in the file so the next person does not 'fix' the inconsistency back into a break. The uniform alias rule now has two stated exceptions: the root (real file, it carries a Claude-only tail) and composition (real file, this gate). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci(guidance): enforce the CLAUDE.md alias rule; scope path-ok to the marked reference The branch's central invariant — a `CLAUDE.md -> AGENTS.md` symlink beside every AGENTS.md at the root and under crates/ — was unguarded: the audit proved a committed symlink deletion left the gate green (a working-tree deletion only tripped the accidental "cannot read guidance file" refusal). Check 5 now judges the git index (`git ls-files -s` + `cat-file`): the alias must be tracked, mode 120000, targeting exactly `AGENTS.md`. The two real-file exceptions are named rows with reasons (the root adapter's Claude-only tail; composition's symlink-refusing ownership walks), and a row that stops matching the tree fails the gate rather than lingering. Sabotage-verified on the real tree: `git rm --cached` on an alias went red naming the pair; converting one to a tracked regular file went red; restore went green (65 aliases verified). Also from the audit: - A `path-ok` marker now vouches for the one reference immediately preceding it instead of exempting its whole line — the audit slipped a fresh dangling path onto a marked line and passed. The `✎` glyph stays line-scoped by documented design. Both in-tree marker usages already sit marker-after-reference and keep working. - Document the structural blind spot: a dead reference whose first segment died with its whole tree (the v1 `src/…` monolith) reads as historical narration and cannot be flagged; only review catches it. - Re-measure the fail-closed floor comment — the shipped one claimed 174 guidance files / ~800 references / 30 globs against a tree that measures 237 / ~2070 / 38 — and add a floor for alias-site discovery. Self-test grows six cases: index-deleted alias, regular-file alias, wrong-target alias, the load-bearing root exception row, exception rows matching reality, and the marker-narrowing exploit. The `--tracked-files` override marks symlinks as `<path> -> <target>`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(guidance): repoint dead skill refs, record alias carve-outs, honest size budgets Content half of the guidance-unification audit fixes: - architecture-video SKILL.md told readers to read `src/tools/README.md` and `src/workspace/README.md` — the v1 monolith is gone (`git ls-files | grep -c '^src/'` is 0) and the gate structurally cannot flag first-segment-dead paths. Repointed at the Reborn successors: `crates/extensions/AGENTS.md` and `crates/domains/ironclaw_memory/README.md`. - guidance-conventions.md now records what only commit messages knew: the composition real-file exception beside the root one; the four sanctioned ironclaw_agent_loop sub-module CLAUDE.md guides; and the alias rule's actual scope (root + crates/**), naming the two out-of-scope AGENTS.md (docs/reborn/contracts, ironclaw_silk_decoder) instead of a "wherever" wording the tree contradicted. - Size budgets re-derived from measurement (family <=220, crate <=160) with the four crate-tier exceptions named and reasoned. The shipped <=150/<=80 numbers were exceeded by 3 family and 24 of 54 crate docs on day one, which made the budget unreadable as a signal. No document was padded or truncated to fit. - Root CLAUDE.md used the dated-correction glyph on the deliberately untracked `.codebase-memory/artifact.json` reference — suppression duty outside the glyph's documented historical-prose meaning. Swapped for `<!-- check-guidance: path-ok -->` beside the reference. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * review(7306): CodeRabbit triage — guidance gate runs for the files it governs, brace globs, honest floors, identity-column family tables, doc-truth fixes Trigger (Major, the inert-guard finding): fast-checks was gated on has_code, whose regex covers none of .claude/, the root AGENTS.md/CLAUDE.md pair, or docs/ — so a PR editing only a rule's paths: trigger skipped the gate built for exactly that change. New has_guidance output OR-s those surfaces into fast-checks only (clippy/JS lanes stay code-scoped); has_code keeps its pinned meaning. Pinned by a ws12_workflow_contracts.py row and verified by replaying representative change lists through the workflow's own extracted EREs. check-guidance.py: glob_to_regex now translates {a,b} brace alternation (nested; unmatched braces stay literal) so a legitimate crates/**/*.{rs,toml} trigger counts as live instead of being reported dead; MIN_RULE_GLOBS 1->20 and MIN_ALIAS_PAIRS 10->40 (~half of measured 38/65, so a degraded parser refuses instead of passing); family-table coverage now requires the crate in a row's identity (first) column — an incidental mention in another row's prose no longer counts (measured 0 regressions on the live tree). Self-tests: +3 (brace trigger end-to-end, duplicate KNOWN_MISSING rows, identity-column regression) and the real-repository case documents its deliberate git coupling. Floors sabotage-verified. Doc truth, measured against code: composition CONTRACT — WS stream shares SseCapacity (stream_events_ws try_acquire, pinned test) replacing 'No WS surface to bound', webui_v2_app returns Result<Router, WebuiServeError>; llm CONTRACT — the circuit breaker wraps failover (apply_decorator_chain order), not the reverse; filesystem CONTRACT — dependency rule now names the real manifest set (+libsql_runtime, +observability); extension_manager AGENTS — the loops layer flip landed (layer = "loops"); four stale 'has no CLAUDE.md' claims updated for the new symlink aliases (config, common, event_store x2); root AGENTS — clippy line gains -- -D warnings (CI denies warnings; unflagged clippy exits 0 with them) and the error bullet routes to .claude/rules/error-handling.md; assistant/webui validation sections document the real lane structure (self-dev-dep unifies test-support on, so the missing shape is the no-dev-deps production lane, the nearai#7119 class). Stale pre-family paths in .rs prose: 594 crates/ironclaw_* citations measured; 130 sit in comments, of which 106 repointed to their family homes (every rewritten path verified to resolve), 10 of those needed deeper repoints (files that moved crates: capability_host.rs, channel_pairing.rs, approval_store_contract.rs, secret_store.rs, loop_contracts instruction_bundle.rs, assistant communication_context.rs, loop_host surface_disclosure.rs, resolver_tests.rs), 24 left deliberately (flat- spelling narration about the family move itself, deleted-crate history, synthetic fixture names, and two nearai#6945-class pointers whose target is gone at every spelling). 464 string-literal citations left: the specificity test resolves legacy spellings through the crate inventory by design. Triage of PR nearai#7306 review comments; no gate weakened, both alias exceptions preserved. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * review(7306): drop the one comment repoint in tests/e2e_trace_runtime_policy_org_ceiling_yolo.rs reborn_pr_test_plan.py has no mapping for this root test (it matches neither the tests/reborn_* partition inventory nor any other arm), so ANY PR touching it fails 'Detect Reborn test scope' — a pre-existing planner gap, confirmed against origin/main with a one-file changed list. The stale crates/ironclaw_runtime_policy comment path inside it stays until the planner learns the file; noted for follow-up rather than smuggling planner surgery into a review-triage branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(contributing): stop annotating the loose iteration clippy line as 'zero warnings' Same class as the root AGENTS.md fix: unflagged clippy exits 0 with warnings, so the annotation overclaimed. CONTRIBUTING's two-tier design (loose iteration block, then a stricter pre-PR block that already carries -- -D warnings) is deliberate and stays; only the claim is aligned. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: recount the frozen WebUI route table after the nearai#7306 merge — 93 -> 97 nearai#7236 (main) added the four operator inspector routes without bumping the stated counts; re-derived on the merged tree: rg -c 'pub const WEBUI_V2_ROUTE_' crates/product/ironclaw_webui/src/webui_v2/descriptors.rs -> 97. Updates the two live claims (webui README, PROPOSAL SS6.9.4 with its strike-through recount convention); historical/superseded 92-row mentions stay as written. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ci): the code-style roll-up must judge fast-checks for guidance-only PRs The has_guidance trigger made fast-checks RUN for .claude/ and root-pair changes, but the roll-up's has_code==false branch exits 0 before it ever reads fast-checks' result — so check-guidance.py could fail and Code Style would still report success. The gate ran and could never block: exactly the inert-guard shape this change exists to remove, reintroduced one layer up. Fixed the way main's docs-publication gate already does it — judged before the early exit, with the reason in a comment. Sabotage-verified: has_guidance=true plus fast-checks=failure now exits 1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Finishes the guidance layer that #7264 started. That PR gave every family and crate a document; this one makes the set coherent — one canonical home per fact, a loader story that is measured rather than assumed, and a CI gate so the whole thing cannot rot again silently.
Prompted by a research pass over how large monorepos structure agent-facing docs (Codex/Cursor/Copilot/Amp conventions,
AGENTS.mdas a Linux Foundation standard, and what kubernetes / uv / ruff / zed / openai-codex actually ship).The problem, measured
CLAUDE.md(286 lines) andAGENTS.md(198 lines) shared zero identical lines — the exact duplication the convention forbids, at the most-loaded file in the repo.CLAUDE.mdfiles outside the Module Specs table, violating a convention one day old.AGENTS.mdcanonical andCLAUDE.mda pointer — which moved working rules out of the only path Claude Code auto-injects.crates/, against kubernetes' one file and openai/codex's two.The loader question, settled empirically
Headless canary experiment with a discriminating control (fixtures and transcripts retained):
CLAUDE.md(regular file)CLAUDE.mdsymlink@AGENTS.mdimport inside a nestedCLAUDE.mdAGENTS.md, noCLAUDE.mdThe negative control is what makes the import result meaningful. Two caveats are recorded in the convention: injection fires only below cwd, and appears not to fire in subagent sessions — so every document must stand alone when read deliberately.
What lands
One rule: wherever an
AGENTS.mdexists, aCLAUDE.mdsymlink sits beside it. Same bytes, no second document to drift. 64 symlinks, plus two named exceptions, both load-bearing:@AGENTS.md+ skills index, MCP graph usage, the REPL logging rule).ironclaw_composition— a real file, becausecomposition_root_embeds_no_prompt_contentrefuses a symlink anywhere under that crate: its ownership walks don't follow links, and stepping over one would let the gate report clean on a subtree it never read. The blanket symlink pass broke that test; the gate was right and the file now explains itself so nobody "fixes" it back into a break.Root pair unified: 484 lines across two forked files → 202, single-sourced. Cut by measurement, not taste — the v1 Job State Machine section (no such machine exists in
crates/), a stale limitations list, and anything the tree derives.Nine stragglers resolved: seven folded to
AGENTS.md-canonical;ironclaw_networkandironclaw_secretsfolded entirely upward into their READMEs (both guidance files deleted — README is now the only crate file). Each surviving crate file names the specific trap that justifies it.Four specs renamed
CLAUDE.md→CONTRACT.md(llm,filesystem,webui,composition) viagit mv, matching the existingidentity/trustprecedent and freeingCLAUDE.mdto be purely mechanical. ~45 references updated.scripts/ci/check-guidance.py— the tier that was missing. Asserts: every path referenced in guidance resolves; every rule/skillpaths:glob matches ≥1 tracked file; every crate appears in its family table and has a README; and the alias rule itself (tracked, index mode120000, targetAGENTS.md), judged from the git index so a committed deletion cannot slip past. 32 self-tests; every check sabotage-proven.It reproduces the original bug as a test case:
.claude/rules/skills.mdhad apaths:trigger naming a nonexistent file, so the rule never fired for the code it governs.Verification
Independent audit of the assembled branch: 0 Critical / 0 High. It confirmed no content lost in the folds (checked bullet-for-bullet on the two crates whose files were deleted entirely), no behavioral regressions in the
.rsdiff — every change is a doc-comment or test-reader retarget, each retarget's parsed section verified present in its new home — and 20+ factual claims verified by command.Its top finding was that the alias rule was unguarded — it simulated a committed symlink deletion and the gate passed. That is now check 5, with the sabotage evidence in the commit. Its other findings are all fixed: two dead
src/references the gate structurally cannot see, the gate's own stale floor measurement, two carve-outs that lived only in a commit message, and a✎glyph doing suppression duty outside its meaning.Gates:
check-guidance0 (2,074 refs, 65 aliases, 0 grandfathered) · self-test 0 (32) ·check-target-tree0 (64/64) · architecture suite 0 (39 result lines) ·fmt0 · composition budget 0 · planner over 152 changed paths 0.Judgment calls, stated
trace_commonsandextension_managerwere not promoted toCONTRACT.mddespite being candidates — measured, both are working-rules-shaped, andCONTRACT.mdis reserved for real specs.crates/**; twoAGENTS.mdoutside that scope are named in the convention rather than silently inconsistent.Known gaps, not hidden
The gate does not extract plain-prose paths or reference-style links, cannot see references whose first segment is a dead top-level directory (the exact blind spot that hid the two
src/rows — now documented in its docstring citing the incident), and does not verify that re-derivation commands still return results. The✎glyph remains line-scoped by design;path-okwas narrowed to vouch only for the reference it follows.🤖 Generated with Claude Code